I have a bunch of classes in a CUDA project that are mostly glorified structs and are dependent on each other by composition:
class A {
public:
typedef boost::shared_ptr<A> Ptr;
A(uint n_elements) { ... // allocate element_indices };
DeviceVector<int>::iterator get_element_indices();
private:
DeviceVector<int> element_indices;
}
class B {
public:
B(uint n_elements) {
... // initialize members
};
A::Ptr get_a();
DevicePointer<int>::iterator get_other_stuff();
private:
A::Ptr a;
DeviceVector<int> other_stuff;
}
DeviceVector is just a wrapper around thrust::device_vectors and the ::iterator can be cast to a raw device pointer. This is needed, as custom kernels are called and require handles to device memory.
Now, I do care about encapsulation, but
raw pointers to the data have to be exposed, so the classes using A and B can run custom kernels on the GPU
a default constructor is not desired, device memory should be allocated automatically --> shared_ptr<T>
only very few methods on A and B are required
So, one could make life much simpler by simply using structs
struct A {
void initialize(uint n_elements);
DeviceVector<int> element_indices;
}
struct B {
void initialize(uint n_elements);
A a;
DeviceVector<int> other_stuff;
}
I'm wondering whether I'm correct that in the sense of encapsulation this is practically equivalent. If so, is there anything that is wrong with the whole concept and might bite at some point?
Make it simple. Don't introduce abstraction and encapsulation before you need it.
It is a good habit to always make your data members private. It may seem at first that your struct is tiny, has no or a couple of member functions, and needs to expose the data members. However, as your program evolves, these "structs" tend to grow and proliferate. Before you know it, all of your code depends on the internals of one of these structs, and a slight change to it will reverberate throughout your code base.
Even if you need to expose raw pointers to the data, it is still a good idea to do that through getters. You may want to change how the data is handled internally, e. g. replace a raw array with an std::vector. If your data member is private and you are using a getter, you can do that without affecting any code using your class. Furthermore, getters let you enforce const-ness, and make a particular piece of data read-only by returning a const pointer.
It is a bit more work up front, but most of the time it pays off in the long run.
It's a trade off.
Using value structs can be a beautifully simple way to group a bunch of data together. They can be very kludgy if you start tacking on a lot of helper routines and rely on them beyond their intended use. Be strict with yourself about when and how to use them and they are fine. Having zero methods on these objects is a good way to make this obvious to yourself.
You may have some set of classes that you use to solve a problem, I'll call it a module. Having value structs within the module are easy to reason about. Outside of the module you have to hope for good behavior. You don't have strict interfaces on them, so you have to hope the compiler will warn you about misuse.
Given that statement, I think they are more appropriate in anonymous or detail namespaces. If they end up in public interfaces, people tend to adding sugar to them. Delete the sugar or refactor it into a first class object with an interface.
I think they are more appropriate as const objects. The problem you fall into is that you are (trying to) maintain the invariance of this "object" everywhere that its used for its entire lifetime. If a different level of abstraction wants them with slight mutations, make a copy. The named parameter idiom is good for this.
Domain Driven Design gives thoughtful, thorough treatment on the subject. It characterizes it a more practical sense of how to understand and facilitate design.
Clean Code also discusses the topic, though from a different perspective. It is more of a morality book.
Both are awesome books and generally recommend outside of this topic.
Related
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
I wish to create a class (class1) which contains another class (class2) as a data member. I then want class2 to know about class1 and be able to communicate with it.
I could have a reference to class1 as a member in class2 but that then means I need to provide a reference to class1 as a parameter in the constructor of class2 and use initialiser lists which I don't want. I'm trying to do this without needing the constructor to do it.
I would like for class2 to have a member function called Initialise which could take in the reference to class1, but this seems impossible without using pointers. What would people recommend here? Thanks in advance.
The code is completely simplified just to get the main idea across :
class class1
{
public:
InitialiseClass2()
{
c2.Initialise(this);
}
private:
class2 c2;
};
class class2
{
public:
Initialise(class1* c1)
{
this->c1 = c1;
}
private:
class1* c1;
};
this seems impossible without using pointers
That is incorrect. Indeed, to handle a reference to some other object, take a reference into a constructor:
class class2
{
public:
class2(class1& c1)
: c1(c1)
{}
private:
class1& c1;
};
The key here is to initialise, not assign, the reference. Whether this is possible depends on whether you can get rid of your Initialise function and settle into RAII (please do!). After that, whether this is actually a good idea depends on your use case; nowadays, you can almost certainly make ownership and lifetime semantics much clearer by using one of the smart-pointer types instead — even if it's just a std::weak_ptr.
Anyway, speaking more generally.
Are pointers "always" bad? No, of course not. I'd almost be tempted to say that managing dynamic memory yourself is "always" bad, but I won't make a generalisation.
Should you avoid them? Yes.
The difference is that the latter is a guideline to steer you away from manual memory management, and the former is an attempted prohibition.
No, using pointers in C++ is not bad at all, and I see this anti-advice over and over again. What is bad is managing pointers by yourself, unless you are creating a pointer-managing low-level entity.
Again, I shall make a very clear distinction. Using pointers is good. Very few real C++ programs can do without USING pointers. Managing pointers is bad, unless you are working on pointer manager.
A pointer can be nullptr whereas a reference must always be bound to something (and cannot be subsequently re-bound to something else).
That's the chief distinction and the primary consideration for your design choice.
Memory management of pointers can be delegated to std::shared_ptr and std::unique_ptr as appropriate.
well, I never had the need to 2 classes to have reciprocal reference and for good reasons, how do you know how to test those classes? If later you need to change something in the way the 2 classes communicates you will probably have to change code in both classes). You can workaround in many ways:
You may need in reality just 1 class ( you have broken into much classes)
You can register a Observer for a class (using a 3rd class, in that case you will end up with a pointer, but at least the 2 classes are less coupled and it is easier test them).
You can think (maybe) to a new interface that require only 1 class to call methods on the other class
You could pass a lambda (or a functor if you do not have C++11) into one of the methods of the class removing the need to a back reference
You could pass a reference of the class inside a method.
Maybe you have to few classes and in reality you need a third class than communicates with both classes.
It is possible you need a Visitor (maybe you really need multiple dispatch)
Some of the workarounds above need pointers, some not. To you the choice ;)
NOTE: However what you are doing is perfectly fine to me (I see you do some trickery only in constructors, but probably you have more omitted code, in wich case that can cause troubles to you). In my case I "register" one class into another, then after the constructor called I have only one class calling the other and not viceversa.
First of all whenever you have a circular dependency in your design think about it twice and make sure it's the way to go. Try to use the Dependency inversion principle in order to analyze and fix your dependencies.
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
Pointers are a powerful programming tool. Like any other feature in the C++ (or in any programming language in general) they have to be used when they are the right tool. In C++ additionally you have access to references which are similar to pointers in usage but with a better syntax. Additionally they can't be null. Thus they always reference a valid object.
So use pointers when you ever need to but try to avoid using raw pointers and prefer a smart pointer as alternative whenever possible. This will protect you against some trivial memory leak problems but you still have to pay attention to your object life-cycle and for each dynamically allocated object you should know clearly who create it and when/whom will release the memory allocated for the object.
Pointers (and references) are very useful in general because they could be used to pass parameters to a method by reference so you avoid passing heavy objects by value in the stack. Imagine the case for example that you have a very big array of heavy objects (which copy/= operator is time consuming) and you would like to sort these objects. One simple method is to use pointers to these objects so instead of moving the whole object during the sorting operation you just move the pointers which are very lightweight data type (size of machine address basically).
I have a class, named Contoller. I want to create one object from that class and change transactionValue and transactionId over and over in runtime. What is the best way for that. I think I can create one object from default constructer and use setControllerValues for new values. Is it best practice?
class Controller{
public:
Controller();
Controller(int,int);
setControllerValues(int,int);
private:
int transactionValue;
int transactionId;
};
int main()
{
Controller ct;
ct.setControllerValues(3,4);
ct.setControllerValues(6,7);
ct.setControllerValues(34,45);
}
EDIT:I heard something about singleton. Should I use it for that?(I changed "skeleton")
Make it a global! No, wait, globals are bad. Make it a singleton! No, wait, singletons are an anti-pattern. Pass it as an argument wherever it's needed! No, wait, tramp data is bad. Make it a global!
What's a person to do?
You pays your money and you takes your choice.
Yes it can be considered good practice. There's nothing wrong there. Maybe you want to do some data validation before writing to your private members in setControllerValues. But a part from that that's pretty straight forward OOP you have there.
It depends.
Some programs are far easier to reason about if there is no mutable state (or very little); multi-threaded programs, for example.
Other object oriented approaches would say getters and setters are anathema.
In terms of performance and creating new objects on the stack, c++11 and the compiler are very good at working out the best way of creating efficient machine code, far better than you and me.
I would consider using the assignment operator. It allows you to use the values from one object to modify another:
class Controller {
public:
Controller& operator=(const Controller& other) {
transactionValue = other.transactionValue;
transactionId = other.transactionId;
return *this;
}
private:
int transactionValue;
int transactionId;
};
And use:
Controller permanent(12, 5678);
//...
permanent = Controller(23, 6789);
What you heard is probably singleton, not skeleton.
For sure, you can use the approach you show, but let me ask you: why would you choose this instead of creating separate objects?
I don't like it for following reasons:
if you really want to ensure a single instance over whole application, you need a proper singleton (not that I like it). Your current implementation doesn't stop anyone to create another controller
it is much easier to handle multiple instances then shared access to single instance. What if you have to provide this object to other functions, or even worse, threads?
it is easier to reason about immutable objects than mutable ones. Mutable state is the cause of good deal of bugs, as it gives more chance to invalidate the type invariants
you actually gain nothing but the cost of calling a constructor which is cheap compared to other logic you need to execute
In short, I don't see any benefit in this approach, without knowing other requirements which might make it more justified. You have introduced a lot of added complexity to save a few instructions during object creation, which is optimized by the compiler anyway. It is a bad tradeoff, IMO.
With regard to singletons, in general I don't like them either :)
Here's why:
I am very suspicious about the class itself knowing its lifecycle concerns (singleton, transient, per-thread, etc). This is something that clients usually know better
It is much harder to test code relying on singletons
shared state + multithreading = nights with debugger
That being said, sometimes they make perfect sense. However, you example doesn't seem to be such a case.
I am am wondering how to create properly properties in C++. In Objective C, I use "#property" (in general with the (nonatomic, retain) attributes).
What is the proper way in C++ ?
Thanks !!
As Seva said, there are no properties in that kind of sense in C++. What you could do: write a class with a boost::share_ptr member variable, and optionally write getter and setter for that member. But that isn't even really necessary, although maybe deemed good behaviour.
typedef boost::shared_ptr<std::string> StringPtrT;
class A {
public:
void setStringProperty(StringPtrT s) { this->string_property = s; }
StringPtrT getStringProperty() const { return this->string_property; }
protected:
StringPtrT string_property;
}
The shared pointer will deal with the sharing and reference counting, basically simulating some kind of "retain" behaviour. IIRC boost shared_ptr types are always atomic, when it comes to updateing the reference counts. However, access to the object itself (de-referencing the pointer) will be non-atomic. You will have to deal with that yourself, if needed.
#Ame's code is correct, but there's no particular requirement to use shared_ptr here. I am very torn on the use of shared_ptr broadly. It can be useful, but introduces a lot of subtle complexity in my experience. It is not the traditional C++ approach. C++ often prefers strong object ownership rather than shared ownership (which is the common model in ObjC). If you do use shared_ptr, it's built-in for Cocoa platforms, so you don't need boost. You may want to read Wrapping C++ – Take 2, Part 2 to get a sense of some of the complexities around shared_ptr (it's a little dated, and some of it is not applicable to ARC code).
That said, #Ame's approach is essentially correct. But you typically would use copying for simple properties rather than shared_ptr. (This is particularly true for strings, which you also copy in most ObjC code.) For someone looking for a style guide, I typically recommend Google's. It's not perfect, but it's very well considered, and it's good to start with something that at least is known to work for a lot of people before inventing your own. (EDIT: See #Matthieu M.'s comment below for a dissenting opinion.)
class MyClass {
public:
...
int num_entries() const { return num_entries_; }
void set_num_entries(int num_entries) { num_entries_ = num_entries; }
private:
int num_entries_;
};
Note the private: is correct here. I disagree with #Ame's use of protected:. Just like ObjC, you should use accessors even inside of classes, and definitely you should use them in subclasses. Allowing subclasses to directly access ivars is fragile. It requires subclasses to have special knowledge of their superclass.
For string properties and other simple or immutable objects, you should generally use the copy constructor rather than anything like shared_ptr. For more complex, mutable objects, C++ typically encourages strong object ownership rather than shared ownership. So there should (in general) be some one object responsible for creating, managing, and destroying that other complex object. Everyone else should just get references from the object's owner. They should never create or destroy the object themselves.
It's not that shared or strict ownership is better IMO. It's just that shared ownership is the ObjC way and all code works that way (and it is extremely elegant in that). Strict ownership is more the C++ way (as much as C++ can be said to have "a way") and trying to shoehorn shared ownership into it is often fragile.
I know what is the difference and how they both work but this question is more about coding style.
Whenever I'm coding I make many classes, they all have variables and some of them are pointers and some are normal variables. I usually prefer variables to pointers if that members lasts as long as the class does but then my code becomes like this:
engine->camera.somevar->x;
// vs
engine->camera->somevar->x;
I don't like the dot in the middle. Or with private variables:
foo_.getName();
// vs
foo_->gatName();
I think that dot "disappears" in a long code. I find -> easier to read in some cases.
My question would be if you use pointers even if the variable is going to be created in the constructor and deleted in the destructor? Is there any style advice in this case?
P.S. I do think that dot is looks better in some cases.
First of all it is bad form to expose member variables.
Second your class should probably never container pointers.
Slight corolary: Classes that contain business logic should never have pointers (as this means they also contain pointer management code and pointer management code should be left to classes that have no business logic but are designed specifically for the purpose of managing pointers (smart pointers and containers).
Pointer management classes (smart pointers/containers) should be designed to manage a single pointer. Managing more than one is much more difficult than you expect and I have yet to find a situation where the extra complexity paid off.
Finally public members should not expose the underlying implementation (you should not provide access to members even via getters/setters). This binds the interface to tightly to the implementation. Instead your public interface should provide a set of actions that can be performed on the object. i.e. methods are verbs.
In C++ it is rare to see pointers.
They are generally hidden inside other classes. But you should get used to using a mixture of -> and . as it all depends on context and what you are trying to convey. As long as the code is clean and readable it does not matter too much.
A personal addendum:
I hate the _ at then end of your identifier it makes the . disapear foo_.getName() I think it would look a lot better as foo.getName()
If the "embedded" struct has exactly the same lifetime as the "parent" struct and it is not referenced anywhere else, I prefer to have it as a member, rather than use a pointer. The produced code is slightly more efficient, since it saves a number of calls to the memory allocator and it avoids a number of pointer dereferences.
It is also easier to handle, since the chance of pointer-related mistakes is reduced.
If, on the other hand, there is the slightest chance that the embedded structure may be referenced somewhere else I prefer to use a separate struct and pointers. That way I won't have to refactor my code if it turns out that the embedded struct needs to be pulled out from its parent.
EDIT:
I guess that means that I usually go with the pointer alternative :-)
EDIT 2:
And yes, my answer is assuming that you really want (or have) to chose between the two i.e. that you write C-style code. The proper object-oriented way to access class members is through get/set functions.
My comments regarding whether to include an actual class instance or a pointer/reference to one are probably still valid, however.
You should not make your choice because you find '->' easier to read :)
Using a member variable is usually better as you can not make mistakes with you pointer.
This said, using a member variable force you to expose your implementation, thus you have to use references. But then you have to initialize then in your constructor, which is not always possible ...
A solution is to use std::auto_ptr or boost::scoped_ptr ot similar smart pointer. There you will get advantage of both solution, with very little drawbacks.
my2c
EDIT:
Some useful links :
Article on std::auto_ptr
boost::scoped_ptr
Pimpl : private implementation
Ideally, you shouldn't use either: you should use getter/setter methods. The performance hit is minimal (the compiler will probably optimize it away, anyway).
The second consideration is that using pointers is a generally dangerous idea, because at some point you're likely to screw it up.
If neither of these faze you, then I'd say all that's left is a matter of personal preference.
Let's say I have a class that allocates some arbitrary member data. There are two common ways that I have seen used (I know that there are others):
class A
{
public:
A();
~A();
//Accessors...
private:
B *mB;
}
A::A()
{
mB = new B();
}
A::~A()
{
delete B;
}
Versus...
class A
{
public:
//Accessors...
private:
B mB;
}
Assume that A itself will be allocated on the heap by consumer code.
In the general case, which method is preferred? I realize that specific situations really encourage one way or the other, but in absence of those demands, is one way preferred? What are the tradeoffs?
The second is the preferred route. Do not use new / delete unless you specifically need a variable to be on the heap or have a lifetime longer than it's container. C++ value types are easier to manage and have less error cases to worry about IMHO
It depends.
In general, If a B is large and unwieldy then it's easier to pass around a pointer to the B than the B itself. So if the B will often be disassociated from the A (f'rinstance if your A's swap B's) then the first way is better.
Using a pointer can also reduce dependencies. If you do it right, A.hh can get by without specifiying what a B is or does (i.e. A.h need not #include "B.hh") so that things that depend on A.hh won't necessarily depend on B.hh.
The price of using pointers is an extra layer of machinery and the dangers of things like lost objects, double-deletion and the dereferencing of uninitialized pointers, so it shouldn't be used unless it actually gives a benefit in your situation. Some people fall in love with pointer techniques and use them everywhere; if they want to improve as programmers they have to grow out of it.
In general, prefer direct composition (the second choice). In that case there is no chance of leaking memory and the object is fully located in a contiguous memory block, allowing better cache locality.
You might use the first option if you're implementing a PIMPL, or you have a need to use one of several possible class types (via inheritance). In that case definitely use a smart pointer (boost::shared_ptr for example) to manage the memory for you.
It depends, mainly, on what you are looking for.
For simplicity's sake: don't use a pointer. Therefore the second choice.
It's easier to manage (no need to worry about memory management, deep copying, deep constness, etc...).
However you might need dynamically allocated attributes sometimes:
if you need polymorphism (otherwise you have a truncation)
if you want to cut down your dependencies (in the header file) --> see PIMPL here
Even in this case though, hand over the responsibility to a smart manager (smart pointer, dedicated pimpl class, etc...)