Why does this code:
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
};
int main(void)
{
B *b = new B(5);
delete b;
}
Result in these errors:
main.cpp: In function ‘int main()’:
main.cpp:13: error: no matching function for call to ‘B::B(int)’
main.cpp:8: note: candidates are: B::B()
main.cpp:8: note: B::B(const B&)
Shouldn't B inherit A's constructor?
(this is using gcc)
If your compiler supports C++11 standard, there is a constructor inheritance using using (pun intended). For more see Wikipedia C++11 article. You write:
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
using A::A;
};
This is all or nothing - you cannot inherit only some constructors, if you write this, you inherit all of them. To inherit only selected ones you need to write the individual constructors manually and call the base constructor as needed from them.
Historically constructors could not be inherited in the C++03 standard. You needed to inherit them manually one by one by calling base implementation on your own.
For templated base classes, refer to this example:
using std::vector;
template<class T>
class my_vector : public vector<T> {
public:
using vector<T>::vector; ///Takes all vector's constructors
/* */
};
Constructors are not inherited. They are called implicitly or explicitly by the child constructor.
The compiler creates a default constructor (one with no arguments) and a default copy constructor (one with an argument which is a reference to the same type). But if you want a constructor that will accept an int, you have to define it explicitly.
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
public:
explicit B(int x) : A(x) { }
};
UPDATE: In C++11, constructors can be inherited. See Suma's answer for details.
This is straight from Bjarne Stroustrup's page:
If you so choose, you can still shoot yourself in the foot by inheriting constructors in a derived class in which you define new member variables needing initialization:
struct B1 {
B1(int) { }
};
struct D1 : B1 {
using B1::B1; // implicitly declares D1(int)
int x;
};
void test()
{
D1 d(6); // Oops: d.x is not initialized
D1 e; // error: D1 has no default constructor
}
note that using another great C++11 feature (member initialization):
int x = 77;
instead of
int x;
would solve the issue
You have to explicitly define the constructor in B and explicitly call the constructor for the parent.
B(int x) : A(x) { }
or
B() : A(5) { }
How about using a template function to bind all constructors?
template <class... T> Derived(T... t) : Base(t...) {}
Correct Code is
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
public:
B(int a):A(a){
}
};
main()
{
B *b = new B(5);
delete b;
}
Error is b/c Class B has not parameter constructor and second it should have base class initializer to call the constructor of Base Class parameter constructor
Here is how I make the derived classes "inherit" all the parent's constructors. I find this is the most straightforward way, since it simply passes all the arguments to the constructor of the parent class.
class Derived : public Parent {
public:
template <typename... Args>
Derived(Args&&... args) : Parent(std::forward<Args>(args)...)
{
}
};
Or if you would like to have a nice macro:
#define PARENT_CONSTRUCTOR(DERIVED, PARENT) \
template<typename... Args> \
DERIVED(Args&&... args) : PARENT(std::forward<Args>(args)...)
class Derived : public Parent
{
public:
PARENT_CONSTRUCTOR(Derived, Parent)
{
}
};
derived class inherits all the members(fields and methods) of the base class, but derived class cannot inherit the constructor of the base class because the constructors are not the members of the class. Instead of inheriting the constructors by the derived class, it only allowed to invoke the constructor of the base class
class A
{
public:
explicit A(int x) {}
};
class B: public A
{
B(int x):A(x);
};
int main(void)
{
B *b = new B(5);
delete b;
}
Related
Given an abstract class A and a data type T, is there a way to enforce implementing a constructor of T on a derived class of A? i.e.
class A {
public:
virtual ~A() {}
virtual void foo() = 0;
};
class B : public A {
public:
B(T t) { ... } // this constructor must be implemented otherwise compilation will error out
};
It is possible with a private token based design. This idea looks something like the following:
#include <utility>
#include <memory>
class A{
private:
struct create_token
{
create_token(const create_token &) = delete;
create_token& operator=(const create_token &) = delete;
create_token(create_token &&) = default;
create_token& operator=(create_token &&) = default;
friend class A;
private:
create_token(){};
};
inline static auto token = create_token{};
protected:
A(create_token) {}
public:
template<class T, typename... ARGUMENTS>
static std::unique_ptr<T> create(ARGUMENTS&&... arguments)
{
// Whatever creation mechanism here
return std::make_unique<T>(create_token{}, std::forward<ARGUMENTS>(arguments)...);
}
};
class B : public A {
public:
template <typename Token> // Can't name A::create_token, it is private
B(Token tok) : A(std::move(tok)) {}
B(){} // Will always lack a `create_token`
};
The example needs a bit of modification for your case (mainly to restrict the constructor) - but the point is that construction can only go through the factory create function.
If A will have it's own constructor which takes parameter and no default constructor
class A {
public:
A(T t) {};
virtual ~A() {}
virtual void foo() = 0;
};
Then all derived classes have to initialize that in their constructor, which means at least one constructor will be needed.
See below examples:
class B : public A {
public:
B(T t):A(t) { ... } // pass parameter to A constructor
};
class C : public A {
public:
C(): A(T{}) { ... } // initialize A with a default T
};
class D : public A {
public:
using A::A; // inherit A's constructors
};
class E : public A {
public:
//error - doesn't work without any constructor!
};
You shouldn't try to force any constructor syntax in derived classes - they may know things which you don't know and they may or may not need T. I'm not sure if forcing constructor signature is even possible.
My best shot would be using CRTP, so that you can check the properties of the derived class within the base class:
template <class Derived>
class A_CRTP //: public A_Base
{
protected:
A() {
static_assert(sizeof(Derived{T}) > 0, "Constructor from T not present");
}
};
class B : public A_CRTP<B> {
public:
B();
B(T); // removing this is a compile-time error.
};
However, this is trivially bypassed:
class C : public B
{
C();
// No C(T) needed, B has that and A doesn't know about C.
};
https://godbolt.org/z/qzd_LJ
That makes this whole exercise somewhat pointless, as it just forces users to take extra steps before they can write the set of constructors they want (see answer of #Yksisarvinen).
Given the following base class:
class Base {
int a, b;
public:
Base(int a, int b=42): a(a), b(b) { }
};
And a class that is derived from base:
class Derived: public Base {
using Base::Base; // inherit Base constructors
bool c;
public:
Derived(int a): Base(a), c(true) { }
Derived(int a, int b): Base(a, b), c(true) { }
};
Is there a way to avoid having to create two separate constructors for Derived and instead overload the inherited Base constructors to initialize the extra member of Derived?
I was thinking to use something like this:
template <typename... Args,
typename std::enable_if_t<std::is_constructible_v<Base, Args&&...>, int> = 0>
explicit Derived(Args&&... args):
Base(std::forward<Args>(args)...), c(true) {}
This is close, but is too verbose and does not work if the the base class's constructors are inherited. i.e. if using Base::Base is present in the class (then it defaults to those constructors and does not initialize the field b).
It works if the base class inherited constructors are not present i.e. removing using Base::Base.
Is this the only way to have this work? i.e. by removing using Base::Base and using a variadic template constructor in each derived class? Is there a less verbose way to overload the inherited constructors?
I am using C++17.
In this case all you need to do is provide c with an in class initializer
class Derived : public Base {
using Base::Base;
bool c = true;
};
allows you to use Base's constructors and will initialize c to true in all cases.
It seems like what you're looking for is a way to inherit Base's constructors while just initializing members of Derived to something specific. For that, we can use a default member initializer:
class Derived: public Base {
public:
using Base::Base;
private:
bool c = true;
};
Constructing a Derived(42) will invoke the Base(int) constructor, but also initialize c to true.
In a derived class If I redefine/overload a function name from a Base class,
then those overloaded functions are not accessable/visible to derived class.
Why is this??
If we don't overload the oveloaded function from the base class in derived class
then all the overloaded versions of that function are available to derived class
objects, why is this??
what is the reason behind this. If you explain this in compiler and linker level
that will be more helpful to me. is it not possible to support this kind of scinario??
Edited
For examble:
class B
{
public:
int f() {}
int f(string s) {}
};
class D : public B
{
public:
int f(int) {}
};
int main()
{
D d;
d.f(1);
//d.f(string); //hidden for D
}
Now object 'd' can't access f() and f(string).
TTBOMK this doesn't have a real technical reason, it's just that Stroustrup, when creating the language, considered this to be the better default. (In this it's similar to the rule that rvalues do not implicitly bind to non-const references.)
You can easily work around it be explicitly bringing base class versions into the derived class' scope:
class base {
public:
void f(int);
void g(int);
};
class derived : public base {
public:
using base::f;
void f(float);
void g(float); // hides base::g
};
or by calling the explicitly:
derived d;
d.base::g(42); // explicitly call base class version
The functions are available, you just need to call them explicitly:
struct A {
void f(){}
};
struct B : public A {
void f() {}
};
int main() {
B b;
b.f(); // call derived function
b.A::f(); // call base function
}
I am trying to inherit a constructor from a base class, but I am getting the error: C2876: 'Poco::ThreadPool' : not all overloads are accessible.
namespace myNamespace{
class ThreadPool : public Poco::ThreadPool{
using Poco::ThreadPool::ThreadPool; // inherits constructors
};
}
Poco::ThreadPool has 3 constructors, 2 public ones both with default initialised arguments, and 1 private one.
How can I only inherit the public constructors?
I am not using c++11.
If you are not using C++11 or later, you can't inherit all base constructors with a single using declaration.
The old way pre-C++11 was to create a corresponding c'tor in the derived class for every c'tor in the base we wanted to expose. So for example:
struct foo {
int _i;
foo(int i = 0) : _i(i) {}
};
struct bar : private foo {
bar() : foo() {} // Use the default argument defined in foo
bar(int i) : foo(i) {} // Use a user supplied argument
};
If you still want to have a c'tor with a default argument, you can do that too:
struct baz : private foo {
baz(int i = 2) : foo(i) {} // We can even change what the default argument is
};
In a derived class If I redefine/overload a function name from a Base class,
then those overloaded functions are not accessable/visible to derived class.
Why is this??
If we don't overload the oveloaded function from the base class in derived class
then all the overloaded versions of that function are available to derived class
objects, why is this??
what is the reason behind this. If you explain this in compiler and linker level
that will be more helpful to me. is it not possible to support this kind of scinario??
Edited
For examble:
class B
{
public:
int f() {}
int f(string s) {}
};
class D : public B
{
public:
int f(int) {}
};
int main()
{
D d;
d.f(1);
//d.f(string); //hidden for D
}
Now object 'd' can't access f() and f(string).
TTBOMK this doesn't have a real technical reason, it's just that Stroustrup, when creating the language, considered this to be the better default. (In this it's similar to the rule that rvalues do not implicitly bind to non-const references.)
You can easily work around it be explicitly bringing base class versions into the derived class' scope:
class base {
public:
void f(int);
void g(int);
};
class derived : public base {
public:
using base::f;
void f(float);
void g(float); // hides base::g
};
or by calling the explicitly:
derived d;
d.base::g(42); // explicitly call base class version
The functions are available, you just need to call them explicitly:
struct A {
void f(){}
};
struct B : public A {
void f() {}
};
int main() {
B b;
b.f(); // call derived function
b.A::f(); // call base function
}