No matching function in multiple inheritance - c++

I'm new to inheritance in C++ and decided to try some experiments to learn about this subject.
The code below shows the hierarchy of classes I'm creating:
classes.h
class base
{
protected:
int _a;
int _b;
int _c;;
base(int b, int c);
};
class sub_one : public virtual base
{
public:
sub_one(int a, int b) : base(a, b)
{
// do some other things here
}
// other members
};
class sub_two : public virtual base
{
protected:
int _d;
public:
sub_two(int a, int b, int c = 0) : base(a, b)
{
// do something
}
// other members
};
class sub_three : public sub_one, public sub_two
{
private:
bool flag;
public:
sub_three(int a, int b, int c = 0) : base(a, b)
{
// do something
}
};
classes.c
base::base(int a, int b)
{
// ...
}
The compiler shows me the messages:
no matching function for call to sub_one::sub_one()
no matching function for call to sub_one::sub_one()
no matching function for call to sub_two::sub_two()
no matching function for call to sub_two::sub_two()
I just can't find out what is wrong.

sub_three(int a, int b, int c = 0) : base(a, b)
{
// do something
}
is equivalent to:
sub_three(int a, int b, int c = 0) : base(a, b), sub_one(), sub_two()
{
// do something
}
Since there are no such constructors in sub_one and sub_two, the compiler reports the errors. You can add default constructors to sub_one and sub_two to remove the errors.

sub_three constructor initializes base, and call the default constructor of sub_one and sub_two which doesn't exist, you may need
class sub_three : public sub_one, public sub_two
{
private:
bool flag;
public:
sub_three(int a, int b, int c = 0)
: base(a, b), sub_one(a,b), sub_two(a,b,c), flag(false)
{
// do something
}
};

Related

deleting or throwing compiler error when a virtual base function is called from a derived class in c++

I have the following code:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class B : public A
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};
class C : public A
{
public:
// do not want f(int a) accessible
void f(int a, int b);
};
I am aware that purely virtual functions cannot be deleted. Is there any way to disable these functions such that a compile time error occurs if an instance of B tries to call f(int,int) or when an instance of C tries to call f(int)
There's no way to do that. You'd need a more complex class hierarchy. Something like this:
class A
{
public:
virtual ~A() {}
};
class BaseForB : public A
{
public:
virtual void f(int a) = 0;
};
class BaseForC : public A
{
public:
virtual void f(int a, int b) = 0;
};
class B : public BaseForB
{
public:
void f(int a) override
{
// details...
}
};
class C : public BaseForC
{
public:
void f(int a, int b) override
{
// details...
}
};
One option is to put a class between A B and A which implements a private version of the function that is final and not callable by instances of B like this:
class A
{
public:
virtual void f(int a) = 0;
virtual void f(int a, int b) = 0;
};
class A_B : public A {
using A::f;
private:
void f(int a, int b) final override {}
};
class B : public A_B
{
public:
// do not want f(int a,int b) accessible
void f(int a);
};

How to Merge two classes A and B to define the functions of a abstract class in C++

In my C++ project, I have an abstract class that defines an interface for a dll. Call it CAbstractClass.
I have a class AClass which has defined functions for all but 1 of the functions of CAbstractClass. How do I create a new non-abstract class C to inherit CAbstractClass?
Here's my attempt. It results in the error 'E0322: object of abstract class type "CClass" is not allowed.
#include "stdafx.h"
class CAbstractClass
{
public:
CAbstractClass(void) {};
~CAbstractClass(void) {};
virtual int Fn1(int a) = 0;
virtual double Fn2(int a, int b) = 0;
virtual int Fn3(double a, double b) = 0;
};
class AClass
{
public:
AClass(void) {};
~AClass(void) {};
int Fn1(int a) { return 2 * a; }
double Fn2(int a, int b) { return (double)a / (double)b; }
};
class BClass
{
public:
BClass(void) {};
~BClass(void) {};
int Fn3(double a, double b) { return (int) (a+b); }
};
// My guess at how to combine all the classes.
class CClass : public CAbstractClass, public AClass, public BClass
{
public:
CClass(void) {};
~CClass(void) {};
};
int main()
{
CClass C; // E0322: object of abstract class type "CClass" is not allowed.
return 0;
}
AClass and BClass also have to inherit from CAbstractClass. Fn1 Fn2 and Fn3 just don't implement virtual methods of abstract class so CClass is also abstract
class AClass : public CAbstractClass {
//...
};
class BClass : public CAbstractClass {
//...
};
class CClass : public virtual AClass, public virtual BClass {
//...
};
I'm not sure if it can be done using a single CAbstractClass, but if you split your abstract interface into two separate abstract interfaces, then it is easy enough:
#include <stdio.h>
class CAbstractClassA
{
public:
virtual int Fn1(int a) = 0;
virtual double Fn2(int a, int b) = 0;
};
class CAbstractClassB
{
public:
virtual int Fn3(double a, double b) = 0;
};
class AClass : public CAbstractClassA
{
public:
int Fn1(int a) { return 2 * a; }
double Fn2(int a, int b) { return (double)a / (double)b; }
};
class BClass : public CAbstractClassB
{
public:
int Fn3(double a, double b) { return (int) (a+b); }
};
// My guess at how to combine all the classes.
class CClass : public AClass, public BClass
{
public:
};
int main()
{
CClass C;
printf("Fn1(5) returns %i\n", C.Fn1(5));
printf("Fn2(10,12) returns %f\n", C.Fn2(10,12));
printf("Fn3(3.14,6.28) returns %i\n", C.Fn3(3.14,6.28));
return 0;
}
Here's what I ended up using. I chose it because it leaves AClass alone. There is more work: every member function that comes from AClass must be defined in BClass. Another benefit is that there's no need for a CClass.
#include "stdafx.h"
class BAbstractClass
{
public:
BAbstractClass(void) {};
~BAbstractClass(void) {};
virtual int Fn1(int a) = 0;
virtual double Fn2(int a, int b) = 0;
virtual int Fn3(double a, double b) = 0;
};
class AClass
{
public:
AClass(void) {};
~AClass(void) {};
int Fn1(int a) { return 2 * a; }
double Fn2(int a, int b) { return (double)a / (double)b; }
};
class BClass : public AClass, public BAbstractClass
{
public:
BClass(void) {};
~BClass(void) {};
int Fn3(double a, double b) { return (int)(a + b); }
// Define a function for each of AClass' member functions.
int Fn1(int a) { return AClass::Fn1(a); }
double Fn2(int a, int b) { return AClass::Fn2(a, b); }
};
int main()
{
BClass B;
return 0;
}

Accessing functions of different classes

I am trying to update the value of a number, to make it 30, by accessing 3 different functions ( they have the same name ) from 3 different classes. Can you please help me ? I have to use the functions in class D. I tried with creating 3 different objects and applying to each of them the function, but it did not work
using namespace std;
int callA=0;
int callB=0;
int callC=0;
class A
{
protected:
void func(int & a)
{
a=a*2;
callA++;
}
};
class B
{
protected:
void func(int & a)
{
a=a*3;
callB++;
}
};
class C
{
protected:
void func(int & a)
{
a=a*5;
callC++;
}
};
class D
{
int val;
public:
//Initially val is 1
D()
{
val=1;
}
//Implement this function
void update_val(int new_val)
{
A a;
B b;
C c;
c.func(b);
b.func(a);
}
};
You can't access from the D class to the func method of A,B,C classes because they are protected.
For accede to protected method of a class your class should be a friend or a derived class.
Otherwise you need to set their visibility to public.
For more read here
Using derived class, this should work;
using namespace std;
int callA=0;
int callB=0;
int callC=0;
class A
{
protected:
void func(int & a)
{
a=a*2;
callA++;
}
};
class B
{
protected:
void func(int & a)
{
a=a*3;
callB++;
}
};
class C
{
protected:
void func(int & a)
{
a=a*5;
callC++;
}
};
class D : public A, public B, public C
{
int val;
public:
//Initially val is 1
D()
{
val=1;
}
//Implement this function
void update_val(int new_val)
{
// if new_val is '1'
//now you can call func methods;
A::func(new_val);
B::func(new_val);
C::func(new_val);
// then if you print new_val it is '30'
// c.func(b); // You can't pass b. b isn't an integer
// b.func(a); // idem
}
};
// ..... //
int main(){
D d;
d.update_val(1);
}
#include<iostream>
using namespace std;
int callA=0;
int callB=0;
int callC=0;
class A
{
public:
void func(int & a)
{
a=a*2;
callA++;
}
};
class B
{
public:
void func(int & a)
{
a=a*3;
callB++;
}
};
class C
{
public:
void func(int & a)
{
a=a*5;
callC++;
}
};
class D
{
public:
int val;
//Initially val is 1
D()
{
val=1;
}
//Implement this function
void update_val()
{
A a;
B b;
C c;
a.func(val);
b.func(val);
c.func(val);
}
};
int main ()
{
D d;
d.update_val();
std::cout<<d.val<<std::endl;
return 0;
}

How can I do second-like constructor in c++?

I have a class A and class B, B here is a subclass of A:
class A {
public:
A(int a) : obj(a) {}
void init() {
if(magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
protected:
string magic_str;
};
class B : public A {
public:
B(int a, double _b) : A(a), b(_b){}
void set_magic_str() {
magic_str = "hello";
}
private:
double b;
};
Above, the init function in A must be constructed in A, but must be called after magic_str is initialized. magic_str must be initialized in class B because there are some user-define logic.
How can I force B to invoke init in A?
To sum up, I want to split constructor code in A into two piece, and between these two piece, some user-defined behavior must be initialized in his subclass B.
One way would be to pass the magic string as an constructor to As constructor and call init in the constructor.
class A {
public:
A(int a, string m) : obj(a), magic_str(m)
{
init();
}
void init() {
if(magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
protected:
string magic_str;
};
class B : public A {
public:
B(int a, double _b) : A(a,get_magic_str()), b(_b){}
static string get_magic_str() {
return "hello";
}
private:
double b;
};
Another way would be to use the builder pattern and let it handle the complex way you want your object to be created:
class A {
public:
A(int a) : obj(a) {}
void init() {
if(magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
protected:
string magic_str;
};
class B : public A {
public:
static B create (int a, double _b) // <-- only allow instances to be created via this function
{
B b = B(a, _b);
b.init();
return b;
}
void set_magic_str() {
magic_str = "hello";
}
private:
B(int a, double _b) : A(a), b(_b){} //maybe protected
double b;
};
As init is a non-private member function of A, B being derived form A, can call init.
Call it after magic_string is set eg. the constructor.
A::init();
Otherwise,change A's constructor , and use this in B.
A(int a, string s)
B(int a, double _b): A (a, magic_str)...
I would change the logic to something like:
class A {
public:
A(int a) : obj(a), c(0) {}
protected:
void set_magic_str(const std::string& s) {
magic_str = s;
if (magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
std::string magic_str;
};
class B : public A {
public:
B(int a, double _b) : A(a), b(_b){}
void set_magic_str() {
A::set_magic_str("hello");
}
private:
double b;
};

Modify constructor parameter values before calling base class constructor

I have following class hierarchy:
class Base { // This class cannot be modified
public:
Base(int a, int b, int c) {
if ( a == 100 && b == 200 && c < 100 ) // whatever condition
throw "Error!";
}
};
class Derived : public Base { // this class can be modified
public:
Derived(int a, int b, int c) : Base(a, b, c) {}
};
class Derived is used in many places in code, so it cannot be replaced with some kind of factory function.
now the question is if there is some construct that would allow me to fix a,b,c values before calling Base constructor?
I know I can use functions like:
Derived(int a, int b, int c) : Base(FixA(a), FixB(b), FixC(c)) {}
int FixA(int a) { /*fix a value*/ return a; }
int FixB(int b) { /*fix b value*/ return b; }
int FixC(int c) { /*fix c value*/ return c; }
but it wont allow me to set correct values in case when a b c values are dependent like in above Base class c-tor example.
I was thinking of extending this to:
Derived(int a, int b, int c) : Base(FixA(a,b,c), FixB(a,b,c), FixC(a,b,c)) {}
int FixA(int a, int& b, int& c) { /*fix a b c values*/ return a; }
int FixB(int& a, int b, int& c) { /*fix a b c values*/ return b; }
int FixC(int& a, int& b, int c) { /*fix a b c values*/ return c; }
I suppose there should also be some kind of flag indicating that fix was already done. I am not sure if this is actually correct c++.
I know the best solution is to actually catch exception.
Consider interposing a class between Derived and Base:
class Derived: public UnpackToBase {
public:
Derived(int a, int b, int c): UnpackToBase(FixParameters(a, b, c))
class UnpackToBase: public Base {
public:
UnpackToBase(FixParameters params): Base(params.a, params.b, params.c)
struct FixParameters {
int a, b, c;
FixParameters(int a, int b, int c): a(a), b(b), c(c) {
// do stuff
}
In C++11 you can use a delegating constructor of Derived:
class Derived: public Base {
public:
Derived(int a, int b, int c): Derived(FixParameters(a, b, c)) { }
Derived(FixParameters params): Base(params.a, params.b, params.c) { }
You can use the singleton pattern to resolve this. Please see the code below. Here the order of initialization of the construction initialization list doesn't matter. However, I'm doubtful, if this can be called elegant.
class Base
{
// This class cannot be modified
public: Base(int a, int b, int c)
{
if ( a == 100 && b == 200 && c < 100 ) // whatever condition
throw "Error!";
}
};
class Validator
{
public:
static Validator& instance(int a_in, int b_in, int c_in)
{
static Validator v(a_in,b_in,c_in);
return v;
}
int& a(){ return m_a;}
int& b(){ return m_b;}
int& c(){ return m_c;}
private:
Validator(int a_in, int b_in, int c_in) : m_a(a_in), m_b(b_in), m_c(c_in)
{
// perform validation and modify the members
// Example validation
if(m_a > 0 && m_b > 0)
{
m_c = 0;
}
}
int m_a;
int m_b;
int m_c;
};
class Derived : public Base
{
// this class can be modified
public:
Derived(int a, int b, int c) : Base(Validator::instance(a, b, c).a(), Validator::instance(a, b, c).b(), Validator::instance(a, b, c).c())
{}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derived d(1,2,3);
return 0;
}
Looks like you don't have a problem with hacking what you have to make something weird happen, so why not use good 'ol macros..
#define FIX_ME(x) //do something
Derived(int a, int b, int c) : Base(FIX_ME(a), FIX_ME(b), FIX_ME(c)) {}