Should copy constructor be private or public - c++

I am writing an abstract class that will be a parent for several other classes. I am thinking the copy constructor should be made private because you are using an abstract class and there is nothing to copy. However, I am not a 100% sure.
Am I correct and if I am not why should it be public or protected?

The copy constructor should be private if you do not want objects of the class to be copied. Otherwise, it should be public.

I think protected is the best choice: it leaves the decision on whether or not the object is copyable to the derived classes, while prohibiting the copying at the abstract class level, preventing the dreaded object slicing.

By making the copy constructor private you'll help prevent inadvertent object slicing, where you make a copy of a derived class but lose all the properties of that derived class. The derived classes can make their own copy constructors that are public and do the right thing.
There's one case where the copy constructor should be protected instead of private, when the abstract class has data members. This doesn't happen very often. The base class can copy the base class members while the derived class copies its own members.
class AbstractBase
{
public:
AbstractBase(const std::string &init) : wtf(init) {}
virtual ~AbstractBase() {}
void DoSomething() = 0;
protected:
AbstractBase(const AbstractBase &r) : wtf(r.wtf) {}
const std::string wtf;
};
class Derived : public AbstractBase
{
public:
// ...
Derived(const Derived &r) : AbstractBase(r), moredata(r.moredata) {}
private:
int moredata;
};

Related

How to inherit constructor from a non-direct base class?

How can I inherit a constructor from Grandpa(Non-Direct Base) to Son? For example:
class Grandpa
{
public:
Grandpa();
~Grandpa();
};
class Dad : public Grandpa
{
public:
Dad();
~Dad();
};
class Son : public Dad
{
public:
using Grandpa::Grandpa;
~Son();
};
ERROR: "can only inherit constructor from direct base"
There is a way how to make it work?
There is no way to inherit a non-direct base class' constructor. However, you can still use it. If you want to pass a value to Grandpa's constructor from Son's constructor, you can do something like this;
class Grandpa
{
public:
Grandpa(string surname){
// some codes in the constructor
}
~Grandpa();
};
class Dad : public Grandpa
{
public:
Dad(string surname) : Grandpa(surname){};
~Dad();
};
class Son : public Dad
{
public:
Son(string surname) : Dad(surname){};
~Son();
};
Here what we do is simply, passing the value from Son's constructor to Dad's constructor, and it is just propagating to the Grandpa's constructor.
The relation of non virtual inheritance is just as direct and strong as membership: a class constructor absolutely controls the invocation of the constructors of its members and the invocation of the constructors of its direct non virtual bases. When a class is written, the way its members and direct non virtual bases is specified in the source code; changing that could invalidate a fundamental invariant of the class.
Using a non virtual base constructor directly from a further derived class would break the C++ model.

Providing a Base Class Constructor

Is it necessary to always provide your base class with a constructor? For example if I had the following base class, and then some derived classes.
class Animal
{
public:
//Is this constructor necessary?
Animal();
virtual ~Animal();
};
class Zebra: public Animal
{
public:
Zebra();
~Zebra();
};
class Elephant: public Animal
{
public:
Elephant();
~Elephant();
};
Assuming that I am creating Animal pointers and then dynamically allocating new Zebra and Elephant objects. If I never intend to create an Animal object, then is there any actual need to explicitly create an Animal constructor?
You don't need to explicitly provide constructor.
A default one is generated (if you don't provide other constructor).
so
class Animal
{
public:
virtual ~Animal();
};
is sufficient.
Derived classes constructors would call Base class constructor (explicitly of implicitly).

virtual base class with public/private constructor Behavior difference

if i run this code
#include<iostream>
using namespace std;
class Final;
class MakeFinal{
public:
friend class Final;
MakeFinal(){cout<<"makefinal\n";}
};
class Final: public virtual MakeFinal{
public:
Final(){cout<<"Final\n";}
};
class Derived:public Final{
public:
Derived(){cout<<"Derived\n";}
};
int main(){
//Final f;
Derived d;
return 0;
}
Output is :
makefinal
Final
Derived
But if i make MakeFinal() constructor private , compiler shows error message. What is this different constructor call hierarchy based on ?
Refer to:
C++ FAQs - virtual inheritance constructors
http://www.parashift.com/c++-faq/virtual-inheritance-ctors.html
Because of the fact that "Initialization list of most-derived-class's ctor directly invokes the virtual base class's ctor. ", your most derived needs to invoke the constructor of the virtual base directly. Therefore, for what you want to do you'd need to make the most derived class a friend too...
Furthermore, it seems that you don't understand virtual inheritance correctly. Refer to this FAQ to understand the purpose and proper use of virtual inheritance.
If your class A have private constructor, you cannot create object a of this class like that (see):
A a;
When an object b of class B that derives from A is created, base class constructor must also be called. If it is private, it cannot be called and the derived object cannot be created.

How to copy private members of a base class in to a derived class's copy constructor

As title suggests, if I have Derived class's copy constructor I need to copy the Base class's members too however I don't have access to the private members. How do I achieve this?
You have below ways to accomplish this:
(1) Create a base copy constructor (not private) and invoke that in derived copy constructor.
example:
class Base {
private: int i;
public: Base(const Base& copy) : i(copy.i) {}
};
class Derived : public Base {
Derived(const Derived& copy) : Base(copy) {}
};
(2) Make the base members to be copied as protected; But this is less preferable way, since you are making assignment and not initialization.
(3) The least preferable way is to make friend class Derived; inside the body of class Base. Use it only if it's absolutely necessary.

If abstract base class is an interface, is it obligatory to call base class constructor in derived class constructor?

class AbstractQuery {
virtual bool isCanBeExecuted()=0;
public:
AbstractQuery() {}
virtual bool Execute()=0;
};
class DropTableQuery: public AbstractQuery {
vector< std::pair< string, string> > QueryContent;
QueryValidate qv;
public:
explicit DropTableQuery(const string& qr): AbstractQuery(), qv(qr) {}
bool Execute();
};
Is it necessary to call base contructor in derived class constructor?
No, in fact for it is unnecessary for the base class to have an explicitly defined constructor (though make sure you have a virtual destructor).
So for a typical interface you could have something like this:
class MyInterface {
public:
virtual ~MyInterface() {}
virtual void execute() = 0;
};
EDIT: Here's a reason why you should have a virtual destructor:
MyInterface* iface = GetMeSomeThingThatSupportsInterface();
delete iface; // this is undefined behaviour if MyInterface doesn't have a virtual destructor
It is never obligatory to explicitly call the base class constructor, unless it has parameters. The compiler will call the constructor automatically. Theoretically the base class still has a constructor, but the compiler may optimize it away into non-existence if it doesn't do anything.
No, not in the example you provided. The base class' default constructors will be called automatically in the same order that the base classes are declared, before any member of the derived class is initialized.
If the base class's constructor does not need any parameters, you do not need to call it in the derived class since it is called as a default constructor. However you need to provide a virtual destructor for your base class even if it is empty. Otherwise compiler will generate a default destructor which is non-virtual by default.