I have created class B (a descendant of QObject), whose public & protected methods should be visible to descendants of B but not to any classes outside of those descendants. So descendant class D inherits from B as private:
class B : public QObject {}
class D: private B {}
However, in D I need to connect to signals emitted from B. The only way I can connect to those signals is to inherit B as public. Otherwise I get a compiler error that
QObject is an inaccessible base of D
Does that mean D must inherit from B as public, and I must create private methods in D to override every public method in B? and somehow hide enums, etc. (Seems like a lot of work, there must be a better way)
I am using Qt 5, and I thought in Qt 5 onwards signals are public. Or is the connect method hidden? Note that B contains some virtual methods that need to be overridden by D, so I cannot just make B an member of D.
Related
I have four classes (classic diamond problem in C++). Let's call the grandparent class A, the parent classes B and C and the child class D. Both B and C have a public member function called attack. I want D to use B's attack function. Class D looks like this:
class D : public B, public C
{
using B::attack;
public:
D(void);
D(std::string &name);
D(D &instance);
~D(void);
D& operator=(D &instance);
};
The attack function simply displays a message on the standard output.
My main looks like this:
int main(void)
{
DiamondTrap dt;
dt.attack();
}
The error I get is the following:
error: 'attack' is a private member of 'D'
note: implicitly declared private here
using B::attack;
Does this mean that using using keyword makes member functions private? I don't know why attack is now private. I can call attack it in my main function from an instance of B, but not from an instance of D. I wish to call it from an instance of D. How can I solve this?
Note I don't know if this is relevant to my problem, but B and C's inheritance is virtual, so only one instance of A is created when an instance of D is created. Also, I am not allowed to use friend keyword in my solution, and I am only allowed to use C++98.
Okay so in the classic diamond inheritance example you have a base class, two classes that inherit from that base class and then another class that inherits from those two, making a nice symmetrical diamond. In that case the two classes inherit virtually from the base class to avoid having two copies of the base class in the most derived class.
But what if there are multiple levels of inheritance in between the base class and the most derived class, as seen in the example diagram below. Do all the classes (B, C, D) need to inherit virtually from their direct base classes or just the ones that are inherit directly (B, C) from the base class? Assuming there are no other classes besides the ones in the diagram.
One does not need to declare C as virtual, since what virtual does is ensure that the class declared as such is contained exactly once, and C is only inherited from once. Basically, the only inheritances that need to be virtual are
class B : public virtual A { ... };
class C : public virtual A { ... };
Source: https://en.cppreference.com/w/cpp/language/derived_class
Suppose I have two classes A and B.
Class A is subclass of X with virtual method known as now_do() so I can easily override it with class A. However most issues are in class B, so I want to include class A in B and override now_do() as A::now_do(){...} but its not possible, So how can I do in order to use variables of class B inside A::now_do(){}.
Code example (class B):
#include "A.cpp"
class B{
public:
int a;
//....
void A::now_do(){
cout<<a<<endl; //Access a member of this class B.
}
};
//But it works when I put outside B class
//However now I can't access members of class B.
void A::now_do(){
cout<<a<<endl; //Can't access a member of this class B.
}
Error I get is: You cannot define member function A::now_do() within B.
Indeed, you can't do what you were trying to do in C++ (nor in any other language, I would think): You see, classes A and B don't share instance information. When you instantiate an A, there is no associated instance of B from which you could take an a value. Nor can you "stick" your a from a B instance into an A instance.
If you want to associate instances of A and B, you will probably want to:
Have a
class AWithB { A instance_of_A; B instance_of_B; };
(that's not a good choice of names of course...)
Make the now_do() a method of AWithB, so it can access both information specific to the A instance and to the B instance
Another alternative would be for class B to inherit from A, and then it could override now_do().
Suppose base class B has a nonvirtual public function f() , which is unfortunately overridden by derived class D.
Then there's a D object d passed to a B pointer pB.
Is there a way to prevent calling pB->f()?
If you can change B, you can either make f virtual, or make it forward to a virtual protected do_f, or various other things.
If you can't change B, you can't stop it's public method being called, and you can't somehow intercept a call to a non-virtual base class method.
Your question essentially asks, “How do I make a function virtual?” You don’t give a reason why you can’t just do that, but maybe you can’t change the declaration of B.
If B has at least one virtual function, you could use RTTI to check if *pB is really a D and cast it to D& if so. You cannot make existing code that takes a B* do so; if your daughter class breaks when you call it as a B, it breaks the contract of that interface.
Otherwise, it might be possible to determine that *pB is a D somehow by calling the B interface, but that would be some rigmarole specific to B and D.
I used to see everywhere that private members of base class are never inherited in derived class, no matter how you inherit the base class (private or protected or public).
But below question has really confused me up. I don't know why the output of this program is 80. It should be 1 byte (which is the size of an empty class in C++) because private members are never inherited.
#include<iostream>
using namespace std;
class base
{
int arr[10];
};
class b1: public base { };
class b2: public base { };
class derived: public b1, public b2 {};
int main(void)
{
cout << sizeof(derived);
return 0;
}
This is mostly a problem of semantics and what different people refer to with inherited. When a type D inherits from a type B, each D object contains a full B object. From that point of view all of the members are there (and some people call this inherited). On the other hand, those members are not accessible from the members of D, and from that point of view the members are as if they were not there (and some people call this not inherited).
Private members of a base (no matter what accesibility) are not accessible from the derived types (assuming no friendship relationship), but they are there, an object of the derived type contains an object of the base type.
Yes, derived classes inherit members from all of their base classes.
The keywords private, public and protected affect only the accessibility of the items they are applied to. If something is not accessible in a particular context and you try to use it, the compiler will give you an error.