patterncppMinor
View programming pattern in C++ without raw pointers
Viewed 0 times
withoutprogrammingviewrawpointerspattern
Problem
I'm trying to achieve, for lack of a better term, a "view" pattern in C++. It's probably most comparable to "views" in the Database world, where one can make a query, and then perhaps aggregate the data, or turn otherwise interact with it without actually duplicating the data.
I've tried to reduce it down to a simple example, where the Data is any integer, and the View is the opposite of that integer (x, -x). This example is pretty contrived, but when we're talking about matrices or other complex forms of data, I could see this pattern become quite useful, especially with respect to generic programming
The code compiles, and fundamentally, works. Unfortunately, there are alternative implementations of this pattern, and that's why I'm asking for a code review. In the long term, are there any reasons that I should be concerned about using this design pattern in my code? Perhaps with respect to:
Some alternative implementations I can think of:
There are some important things to note about this code as well. The View class can not be copied or moved, meaning that its lifespan is identical to that of the Data class. There is also the flexibility of being able to mutate the View class when Data::view() is called, for example, setting a scalar. The two classes are mutual friends, but the Data only really has a use for the constructor of the View.
Data.h
View.h
```
#ifndef VIEW_H
#define VIEW_H
class Data;
class View {
public:
Vie
I've tried to reduce it down to a simple example, where the Data is any integer, and the View is the opposite of that integer (x, -x). This example is pretty contrived, but when we're talking about matrices or other complex forms of data, I could see this pattern become quite useful, especially with respect to generic programming
The code compiles, and fundamentally, works. Unfortunately, there are alternative implementations of this pattern, and that's why I'm asking for a code review. In the long term, are there any reasons that I should be concerned about using this design pattern in my code? Perhaps with respect to:
- Avoiding, Identifying Bugs
- Class Flexibility
- Code Readability
Some alternative implementations I can think of:
- Using raw pointers instead of const references for the Data class
- Using inheritance and implementing the "view" functions within the Data class
There are some important things to note about this code as well. The View class can not be copied or moved, meaning that its lifespan is identical to that of the Data class. There is also the flexibility of being able to mutate the View class when Data::view() is called, for example, setting a scalar. The two classes are mutual friends, but the Data only really has a use for the constructor of the View.
Data.h
#ifndef DATA_H
#define DATA_H
#include "View.h"
class Data {
public:
Data(const int value) :
view_(*this),
value_(value)
{}
const View& view() const { return view_; }
int value() const { return value_; }
private:
friend View;
const int value_;
const View view_;
};
#endif // DATA_HView.h
```
#ifndef VIEW_H
#define VIEW_H
class Data;
class View {
public:
Vie
Solution
-
The intentions are clearly expressed, the code is clean and easily understood. As far as I can see there is no obvious problems.
-
I don't know what Standard mandates here. Fix is simple: add a forward declaration
-
In general I am not sure that this is a right approach.
The intentions are clearly expressed, the code is clean and easily understood. As far as I can see there is no obvious problems.
-
clang-600.0.57 failed to compile the example:./view.h:15:9: error: unknown type name 'Data'
const Data& data_;
^
./view.h:16:14: error: unknown type name 'Data'
View(const Data& data) : data_(data) {}
^I don't know what Standard mandates here. Fix is simple: add a forward declaration
class Data; to view.h.-
In general I am not sure that this is a right approach.
Data must be aware of View anyway (for example, to add another View you need to modify Data). So implementing views as member functions seems more direct.Code Snippets
./view.h:15:9: error: unknown type name 'Data'
const Data& data_;
^
./view.h:16:14: error: unknown type name 'Data'
View(const Data& data) : data_(data) {}
^Context
StackExchange Code Review Q#124420, answer score: 3
Revisions (0)
No revisions yet.