Class members that are objects - Pointers or not? C++

后端 未结 11 1907
挽巷
挽巷 2020-12-07 12:59

If I create a class MyClass and it has some private member say MyOtherClass, is it better to make MyOtherClass a pointer or not? What does it mean also to have it as not a

相关标签:
11条回答
  • 2020-12-07 13:07

    Some advantages of pointer member:

    • The child (MyOtherClass) object can have different lifetime than its parent (MyClass).
    • The object can possibly be shared between several MyClass (or other) objects.
    • When compiling the header file for MyClass, the compiler doesn't necessarily have to know the definition of MyOtherClass. You don't have to include its header, thus decreasing compile times.
    • Makes MyClass size smaller. This can be important for performance if your code does a lot of copying of MyClass objects. You can just copy the MyOtherClass pointer and implement some kind of reference counting system.

    Advantages of having the member as an object:

    • You don't have to explicitely write code to create and destroy the object. It's easier and and less error-prone.
    • Makes memory management more efficient because only one block of memory needs to be allocated instead of two.
    • Implementing assignment operators, copy/move constructors etc is much simpler.
    • More intuitive
    0 讨论(0)
  • 2020-12-07 13:20

    It depends... :-)

    If you use pointers to say a class A, you have to create the object of type A e.g. in the constructor of your class

     m_pA = new A();
    

    Moreover, don't forget to destroy the object in the destructor or you have a memory leak:

    delete m_pA; 
    m_pA = NULL;
    

    Instead, having an object of type A aggregated in your class is easier, you can't forget to destroy it, because this is done automatically at the end of lifetime of your object.

    On the other hand, having a pointer has the following advantages:

    • If your object is allocated on the stack and type A uses a lot of memory this won't be allocated from the stack but from the heap.

    • You can construct your A object later (e.g. in a method Create) or destroy it earlier (in method Close)

    0 讨论(0)
  • 2020-12-07 13:22

    The simple thing to do is to declare your members as objects. This way, you do not have to care about copy construction, destruction and assignment. This is all taken care of automatically.

    However, there are still some cases when you want pointers. After all, managed languages (like C# or Java) actually hold member objects by pointers.

    The most obvious case is when the object to be kept is polymorphic. In Qt, as you pointed out, most objects belong to a huge hierarchy of polymorphic classes, and holding them by pointers is mandatory since you don't know at advance what size will the member object have.

    Please beware of some common pitfalls in this case, especially when you deal with generic classes. Exception safety is a big concern:

    struct Foo
    {
        Foo() 
        {
            bar_ = new Bar();
            baz_ = new Baz(); // If this line throw, bar_ is never reclaimed
                              // See copy constructor for a workaround
        }
    
        Foo(Foo const& x)
        {
            bar_ = x.bar_.clone();
            try { baz_ = x.baz_.clone(); }
            catch (...) { delete bar_; throw; }
        }
    
        // Copy and swap idiom is perfect for this.
        // It yields exception safe operator= if the copy constructor
        // is exception safe.
        void swap(Foo& x) throw()
        { std::swap(bar_, x.bar_); std::swap(baz_, x.baz_); }
    
        Foo& operator=(Foo x) { x.swap(*this); return *this; }
    
    private:
        Bar* bar_;
        Baz* baz_;
    };
    

    As you see, it is quite cumbersome to have exception safe constructors in the presence of pointers. You should look at RAII and smart pointers (there are plenty of resources here and somewhere else on the web).

    0 讨论(0)
  • 2020-12-07 13:23

    This question could be deliberated endlessly, but the basics are:

    If MyOtherClass is not a pointer:

    • The creation and destruction of MyOtherClass is automatic, which can reduce bugs.
    • The memory used by MyOtherClass is local to the MyClassInstance, which could improve performance.

    If MyOtherClass is a pointer:

    • The creation and destruction of MyOtherClass is your responsibility
    • MyOtherClass may be NULL, which could have meaning in your context and could save memory
    • Two instances of MyClass could share the same MyOtherClass
    0 讨论(0)
  • 2020-12-07 13:24

    I follow the following rule: if the member object lives and dies with the encapsulating object, do not use pointers. You will need a pointer if the member object has to outlive the encapsulating object for some reason. Depends on the task at hand.

    Usually you use a pointer if the member object is given to you and not created by you. Then you usually don't have to destroy it either.

    0 讨论(0)
  • 2020-12-07 13:26

    An advantage of the parent class maintaining the relation to a member object as a (std::auto_ptr) pointer to the member object is that you can forward declare the object rather than having to include the object's header file.

    This decouples the classes at build time allowing to modify the member object's header class without causing all the clients of your parent class to be recompiled as well even though they probably do not access the member object's functions.

    When you use an auto_ptr, you only need to take care of construction, which you could typically do in the initializer list. Destruction along with the parent object is guaranteed by the auto_ptr.

    0 讨论(0)
提交回复
热议问题