Let's consider two classes A and B with the following interface:
class A {
public:
    virtual void start() {} //default implementation does nothing
};
class B {
public:
    void start() {/*do some stuff*/}
};
and then a third class which inherits from both, A publicly because it implements this "interface", and B privately because that's implementation detail.
However, in this specific implementation, start() only has to contain a call to B::start(). So I thought I could use a shortcut and do the following:
class C: public A, private B {
public:
    using B::start;
};
and be done with it, but apparently it doesn't work. So I get using private base function doesn't work in order to override virtuals. From that, two questions:
start() functions with the exact same signature in C and yet the compiler seems fine with it and only calls A::start().EDIT: A few precisions:
C objects through A pointers.B::start(), I was specifically wondering if a using declaration could indeed "override" a virtual, and if not, how this was allowed to have both functions coexist.virtual inheritance for simplicity.You can override virtual functions defined in a base class from the Visual Studio Properties window.
When the method is declared as virtual in a base class, and the same definition exists in a derived class, there is no need for override, but a different definition will only work if the method is overridden in the derived class. Two important rules: By default, methods are non-virtual, and they cannot be overridden.
It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used. A class may have virtual destructor but it cannot have a virtual constructor.
A virtual function is a member function in the base class that we expect to redefine in derived classes. Basically, a virtual function is used in the base class in order to ensure that the function is overridden. This especially applies to cases where a pointer of base class points to an object of a derived class.
Is there any way to make this work as I supposed it may have worked?
You should override the member function and explicitly call B::start():
class C: public A, private B {
public:
    void start() override { B::start(); }
};
Why would the compiler accept this code as valid? As I see it there are now two
start()functions with the exact same signature in C and yet the compiler seems fine with it and only callsA::start().
You are right, there are two member functions accessible in C (A::start() and B::start()). And in class C, without overriding start() or making the start() of any of the base classes visible by doing a using ...::start(), you will have ambiguity error when trying to call the member function using unqalified namelookup from an object of C. 
class A {
public:
    virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
    void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
};
int main(){
    A* a = new C();
    a->start();       //Ok, calls A::start()
    C* c = new C();
    c->start();       //Error, ambiguous         
}
To fix that, you will have to use the qualified name such as:
    C* c = new C();
    c->A::start();       //Ok, calls A::start()
Now, doing a using B::start() in class C simply declares the start() to refer to B::start() whenever such name is used from an object of C
class A {
public:
    virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
    void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
     using B::start();
};
int main(){
    A* a = new C();
    a->start();       //Ok, calls A::start()
    C* c = new C();
    c->start();       //Ok, calls B::start()
}
using B::start makes the function void B::start() visible in C, it does not override it. To call make all the above unqualified member function call, to call B::start(), you should override the member function in C, and make it call B::start()
class A {
public:
    virtual void start() { std::cout << "From A\n"; }
};
class B {
public:
    void start() { std::cout << "From B\n"; }
};
class C: public A, private B {
public:
    void start() override { B::start(); }
};
int main(){
    A* a = new C();
    a->start();         //Ok, calls C::start() which in turn calls B::start()
                        //    ^^^^^^^^^^^^^^^^ - by virtual dispatch
    C* c = new C();
    c->start();         //Ok, calls C::start() which in turn calls B::start()
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With