No default constructor, When there is [duplicate] - c++

This question already has answers here:
no default constructor exists for class
(5 answers)
Closed 1 year ago.
Why do I get the error "No default constructor exists for class "Sub", even though I have the constructor for Sub class"
class Base{
private:
int x;
public:
Base(int number)
{
x = number;
}
virtual void print(void) = 0;
};
class Sub: public Base{
public:
Sub(int x): Base(x) {
}
void print()
{
cout << "Testing" << endl;
}
};

A default constructor is one taking NO arguments. A default constructor is one which requires no provided arguments.
Base() and Base(args = default) are both considered default constructors, as no arguments are required. Please note the second one is Pseudo Code.
class Base{
private:
int x;
public:
Base(int number)
{
x = number;
}
virtual void print(void) = 0;
};
class Sub: public Base{
public:
Sub(int x): Base(x) {
}
void print()
{
cout << "Testing" << endl;
}
};
Your code definitely does not have a default constructor.
Declaring a constructor automatically disables the compiler-created default contructor.
More info:
https://en.cppreference.com/w/cpp/language/default_constructor
https://www.geeksforgeeks.org/constructors-c/
https://www.ibm.com/docs/en/zos/2.2.0?topic=only-default-constructors-c
https://www.w3schools.com/cpp/cpp_constructors.asp
https://learn.microsoft.com/en-us/cpp/cpp/constructors-cpp
https://www.learncpp.com/cpp-tutorial/constructors/

Related

How to initialize an `const int` member in a base class when constructing child? [duplicate]

This question already has answers here:
How can I initialize base class member variables in derived class constructor?
(7 answers)
Closed 24 days ago.
#include <iostream>
class A {
public:
const int HP = 200;
A(){
std::cout << this->HP << std::endl;
}
};
class B : public A {
public:
B();
};
Constructing a B object will construct the A potion first.
I expect to reinitialize HP so that B() can print new HP.
Is this feasible for a base class const member ?
I need a member shared between base and child but to be constant in one instance of class, any suggestions?
You can add a constructor to A (and if needed also to B) that accepts the value for the const int member.
Then when you invoke A constructor from B constructor via the initializer list, you can pass this const value to the base.
Code example:
#include <iostream>
class A {
public:
const int HP = 200;
A() {
std::cout << this->HP << std::endl;
}
//----vvvvvv----vvvvvv--
A(int hp) : HP(hp) {
std::cout << this->HP << std::endl;
}
};
class B : public A {
public:
B() {};
//----vvvvvv----vvvvv--
B(int hp) : A(hp) {}
};
int main()
{
B b1;
B b2{ 99 };
}
Output:
200
99
Note: B can also be left as is (without an additional constructor), and pass the required const value to the base.

C++11 Declaring factory a friend of base class

I'm trying to create a factory for derived classes. I only want the factory to be able to create instances of the derived classes so I've made the base constructor protected; the derived classes just use the base class constructors so their constructors are protected also.
I tried to declare the factory as a friend of the base class so that it could access the protected constructor. When I compile using this command
clang++ -std=c++11 -stdlib=libc++ Friends.cpp -o Friends
I get this error:
Friends.cpp:23:20: error: calling a protected constructor of class 'A'
return new T(i);
^
Friends.cpp:42:16: note: in instantiation of function template specialization 'Create<A>' requested
here
A* a = Create<A>(1);
^
Friends.cpp:30:25: note: declared protected here
using Base::Base;
^
Along with a similar error for derived class B.
I get the feeling from reading other questions on stackoverflow.com, that this isn't possible in C++11, but I'm not sure why. Can someone explain why this won't work and perhaps an alternative?
Example code
#include <iostream>
using namespace std;
// Forward declaration
template<class T> T* Create(int i);
class Base {
public:
template<class T>
friend T* Create(int);
virtual void say() = 0;
protected:
Base(int i): i(i) { } // This won't compile
int i;
};
// Factory for Base class
template<class T>
T* Create(int i){
return new T(i);
}
class A: public Base {
public:
using Base::Base;
void say() { cout << "I am A and have a value of " << i << endl; }
};
class B: public Base{
public:
using Base::Base;
void say() { cout << "I am B and have a value of " << i << endl; }
};
int main(){
cout << "I'm creating A." << endl;
A* a = Create<A>(1);
a->say();
cout << "I'm creating B." << endl;
B* b = Create<B>(2);
b->say();
return 0;
}
When you inherit a constructor from a base class it retains the access of the original constructor, regardless of where you place the using declaration in the derived class.
From ยง12.9/4 [class.inhctor]
A constructor so declared has the same access as the corresponding constructor in X. ...
You can fix the error if you explicitly add constructors to derived classes instead of inheriting them from Base.
A(int i) : Base(i) {}
and
B(int i) : Base(i) {}
Live demo
Another solution, of course, is to make Base's constructor public. You could also make its destructor protected, but it's not necessary since the class cannot be instantiated anyway due to the pure virtual member function.
class Base {
public:
template<class T>
friend T* Create(int);
virtual void say() = 0;
Base(int i): i(i) { } // This won't compile
int i;
protected:
~Base() {}
};
Live demo
Friendship does not go down the inheritance tree. Create is friend of Base, and therefore can not access the protected A::A(int) and B::B(int).
Possible solutions include:
Make new friendships (A, B and further child classes should be friends of Create)
Use public constructors as mentioned by #Snps
Use an external class that only Base (and therefore also its friend, Create) can create and the rest can only copy. Idea from here.
Code for last solution:
#include <iostream>
using namespace std;
// Forward declaration
template<class T> T* Create(int i);
class Base {
class AccessKey {
friend class Base;
AccessKey() {};
public:
AccessKey(const AccessKey& o) {}
};
static AccessKey getAccessKey() { return AccessKey(); }
public:
template<class T>
friend T* Create(int);
virtual void say() = 0;
Base(int i, AccessKey k): i(i) { } // This can be public as it can be called without and AccessKey object
protected:
int i;
};
// Factory for Base class
template<class T>
T* Create(int i){
return new T(i, Base::getAccessKey());
}
class A: public Base {
public:
using Base::Base;
void say() { cout << "I am A and have a value of " << i << endl; }
};
class B: public Base{
public:
using Base::Base;
void say() { cout << "I am B and have a value of " << i << endl; }
};
int main(){
cout << "I'm creating A." << endl;
A* a = Create<A>(1);
a->say();
cout << "I'm creating B." << endl;
B* b = Create<B>(2);
b->say();
return 0;
}
I would be tempted to make the Create() function a static member of Base and then just make all the derived classes friends of Base:
Run This
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {}
// Factory for Base class
template<class T>
static T* Create(int i) {
static_assert(std::is_base_of<Base, T>::value, "Needs to be derived from Base");
return new T(i);
}
virtual void say() = 0;
protected:
Base(int i): i(i) { }
int i;
};
class A: public Base {
friend Base; // Allow Base to construct
public:
using Base::Base;
void say() { cout << "I am A and have a value of " << i << endl; }
};
class B: public Base {
friend Base; // Allow Base to construct
public:
using Base::Base;
void say() { cout << "I am B and have a value of " << i << endl; }
};
int main(){
cout << "I'm creating A." << endl;
A* a = Base::Create<A>(1);
a->say();
cout << "I'm creating B." << endl;
B* b = Base::Create<B>(2);
b->say();
return 0;
}
EDIT: Added static_assert
EDIT: Added link to run code

How to use a copy constructor with a base class?

I'm confused about base classes and copy constructors.
Say I have a class
class A {
public:
A(int m) : m(m) { return; }
virtual ~A() { return; }
int m;
}
And a class that inherits this
class B : public A {
public:
B(int n, int m) : A(m), n(n) { return; }
vitual ~B() { return; }
int n;
}
When I copy class B, how do I ensure that the m value in class A is copied as well?
The default copy constructor will copy all of the member variables, no matter whether they reside in the base class or a derived class.
If you create your own copy constructor for class B you will need to copy the class A members yourself, or better yet use the copy constructor for class A in the initializer list.
class B : public A {
public:
// ...
B(const B & b) : A(b), n(b.n) {}
// ...
};
The base copy constructor will be called before the derived copy constructor automatically. It's the same as for a regular constructor. (More accurately, the base constructor is called by derived initialization list before derived constructor continues). In your case, the default copy constructors are sufficient.
Be careful, however, that you do not copy a B into an A (search object splicing).
This code is your code just copy constructors are added with a class:
#include <iostream>
using namespace std;
struct Int
{
Int ()
{
}
Int(const Int&)
{
cout<< "Int copied" "\n";
}
};
class A
{
Int m;
public:
A(Int m) : m(m)
{
}
virtual ~A()
{
}
};
class B : public A
{
Int n;
public:
B(Int n, Int m) : A(m), n(n)
{
}
virtual ~B()
{
}
};
void f(B)
{
}
int main()
{
Int m,n;
B b(m,n);
cout<< "\n" "start:" "\n";
f(b);
cout<< "end";
}
Ubuntu Qt Creator Output says both are copied.
One can think there's a hidden member with type B in A and this hidden member can be initialized or copied as a usual member as in the above program with:
B(Int n, Int m) : A(m), n(n)
You should not return from a constructor/destructor, not even void.

How to deal with name hiding when base class function already overloaded with different access

Class foo act as interface, it has a pure virtual function and also provide some public overloaded function with same name for convenience so that derived class won't need to provide them in every implementation.
But since derived class must override the pure virtual function, it hides foo's public function.
I tried with "using foo::A", but it won't work because "using" will bring all function including the private one and result in compiler error "error C2876: 'foo' : not all overloads are accessible".
class foo
{
private:
virtual void A(int a)=0;
public:
void A()
{
A(1000);
}
void A(int a, int b)
{
A(a+b);
}
};
class bar : public foo
{
private:
virtual void A(int a)
{
cout << a << "\n";
}
};
int main()
{
bar x;
x.A();
return 0;
}
I know I can redefine every overloaded function in every class which derived from foo, but this defeat the purpose of convenience.
Or I can cast bar to foo before calling A(), but this approach will get confused since I need to remember which function is define in which class. For example:
class foo
{
private:
virtual void A(int a)=0;
public:
void A()
{
A(1000);
}
void A(int a, int b)
{
A(a+b);
}
};
class bar : public foo
{
private:
virtual void A(int a)
{
cout << "bar:" << a << "\n";
}
public:
void A(int a, int b, int c)
{
A(a+b+c);
}
};
class foobar : public bar
{
private:
virtual void A(int a)
{
cout << "foobar:" << a << "\n";
}
};
int main()
{
foobar x;
x.foo::A();
x.bar::A(1,2,3);
return 0;
}
I need to clearly remember A withouth argument come from foo, and A with three arguments come from bar. This is also not good for convenience.
When using the non virtual interface idiom, it's safer, and more explicit, to name the two functions (the public non-virtual and the private virtual) differently.
This shows well what the code does, and would solve your problem:
class foo
{
private:
virtual void doA(int a)=0;
public:
void A()
{
doA(1000);
}
void A(int a, int b)
{
doA(a+b);
}
};
And of course don't forget to change in the hierarchy.

How does constructor delegation interact with non-static data member initialization?

Say I have some code like this:
class Foo
{
public:
Foo(int v) : value(v) {}
Foo() : Foo(42) {}
private:
int value = 666;
};
Does the default ctor set value to 42 or 666? I guess I would hope for 42 since that is an explicit call but I could imagine the other way too.
How about with inheritance?
class Base
{
public:
Base() { }
virtual ~Base() { }
virtual int f() = 0;
};
class Bar : public Base
{
public:
Bar(int _i) : Base(), i(_i) { }
Bar() : Bar(-1) { }
virtual ~Bar() { }
virtual int f() { }
private:
int i = 777;
};
Again, I would hope for i == -1.
Thanks.
The in class body member initializer is just a default. If the member initializer list of a constructor initializes the member too, it takes precedence always.
This is specified by 12.6.2p9 in the C++11 spec.