I wrote a small test program with a sample class that also contains a self-defined constructor, destructor, copy constructor, and assignment operator. I was surprised when I realized that the copy constructor was not called at all, although I implemented functions with return values of my class and strings of type Object o1; Object o2(o1); Object o1; Object o2(o1);
innerclass.hpp:
#include <iostream> class OuterClass { public: OuterClass() { std::cout << "OuterClass Constructor" << std::endl; } ~OuterClass() { std::cout << "OuterClass Destructor" << std::endl; } OuterClass(const OuterClass & rhs) { std::cout << "OuterClass Copy" << std::endl; } OuterClass & operator=(const OuterClass & rhs) { std::cout << "OuterClass Assignment" << std::endl; } class InnerClass { public: InnerClass() : m_int(0) { std::cout << "InnerClass Constructor" << std::endl; } InnerClass(const InnerClass & rhs) : m_int(rhs.m_int) { std::cout << "InnerClass Copy" << std::endl; } InnerClass & operator=(const InnerClass & rhs) { std::cout << "InnerClass Assignment" << std::endl; m_int = rhs.m_int; return *this; } ~InnerClass() { std::cout << "InnerClass Destructor" << std::endl; } void sayHello() { std::cout << "Hello!" << std::endl; } private: int m_int; }; InnerClass innerClass() { InnerClass ic; std::cout << "innerClass() method" << std::endl; return ic; } };
innerclass.cpp:
#include "innerclass.hpp" int main(void) { std::cout << std::endl << "1st try:" << std::endl; OuterClass oc; OuterClass oc2(oc); oc.innerClass().sayHello(); std::cout << std::endl << "2nd try:" << std::endl; OuterClass::InnerClass ic(oc.innerClass()); ic = oc.innerClass(); }
Output:
1st try: OuterClass Constructor OuterClass Copy InnerClass Constructor innerClass() method Hello! InnerClass Destructor 2nd try: InnerClass Constructor innerClass() method InnerClass Constructor innerClass() method InnerClass Assignment InnerClass Destructor InnerClass Destructor OuterClass Destructor OuterClass Destructor
After some research, I read that there is no guarantee that the compiler will use an explicitly defined copy constructor. I do not understand this behavior. Why does the copy constructor even exist if we don’t know what it is called? How does the compiler decide if it uses it?
Or, even better, is there a way to force the compiler to use a self-defined copy constructor?
Chris source share