N
nguillot
Hello.
Here an example of is-implemented-in-term-of (or has-a) relation, with
a private inheritance:
(please, this is sample code to illustrate my question, don't suggest
me to use composition, even if you would be right).
every class that wants to log must inherit from the following class:
class Loggable
{
protected:
Loggable(std::string className) : className_(className) {}
void Log(std::string text)
{
// a log function, for instance:
std::cout << className_ << ": " << text << endl;
}
private:
std::string className_;
};
Let's have a class A that wants to log:
class A : private Loggable
{
public:
A() : Loggable("A")
{
Log("blabla");
}
};
So far, so good
Now, let's have a class B that wants to log, and inherits from A:
class B : private Loggable, public A
{
public:
B() : Loggable("B")
{
Log("blbblb");
}
};
It produces a warning:
warning: direct base ‘Loggable’ inaccessible in ‘B’ due to ambiguity
and an error:
error: reference to ‘Log’ is ambiguous
error: candidates are: void Loggable::Log(std::string)
error: void Loggable::Log(std::string)
A solution would to use virtual inheritance from Loggable, but I think
it's not what I want:
Maybe it's ambigous for the compiler which Loggable base to use when
we use Log in B, but it's not: as I use private inheritance, the
A::Log should'nt be available in B...
So... is their another solution than virtual inheritance and
composition?
Another question: I don't understand why virtual inheritance fix the
issue: in memory I still have an instance of loggable for A and
another instance for B.
Thank you for your answers.
Here an example of is-implemented-in-term-of (or has-a) relation, with
a private inheritance:
(please, this is sample code to illustrate my question, don't suggest
me to use composition, even if you would be right).
every class that wants to log must inherit from the following class:
class Loggable
{
protected:
Loggable(std::string className) : className_(className) {}
void Log(std::string text)
{
// a log function, for instance:
std::cout << className_ << ": " << text << endl;
}
private:
std::string className_;
};
Let's have a class A that wants to log:
class A : private Loggable
{
public:
A() : Loggable("A")
{
Log("blabla");
}
};
So far, so good
Now, let's have a class B that wants to log, and inherits from A:
class B : private Loggable, public A
{
public:
B() : Loggable("B")
{
Log("blbblb");
}
};
It produces a warning:
warning: direct base ‘Loggable’ inaccessible in ‘B’ due to ambiguity
and an error:
error: reference to ‘Log’ is ambiguous
error: candidates are: void Loggable::Log(std::string)
error: void Loggable::Log(std::string)
A solution would to use virtual inheritance from Loggable, but I think
it's not what I want:
Maybe it's ambigous for the compiler which Loggable base to use when
we use Log in B, but it's not: as I use private inheritance, the
A::Log should'nt be available in B...
So... is their another solution than virtual inheritance and
composition?
Another question: I don't understand why virtual inheritance fix the
issue: in memory I still have an instance of loggable for A and
another instance for B.
Thank you for your answers.