This question already has answers here:
C++ inheritance - inaccessible base?
(2 answers)
Closed 7 years ago.
I've tried making a basic C++ program with some classes and ran into a problem. The program looks like:
#include<iostream>
using namespace std;
class A {
public:
int i;
A(int ai) {this->i = ai;}
A() {}
};
class B : A {
public:
A aa;
B(A &a) : A(a.i) {
aa = a;
}
};
int main()
{
A a(5);
B b(a);
cout << "Hello World!" << b.i;
return 0;
}
The program fails to compile with:
In function 'int main()':
Line 6: error: 'int A::i' is inaccessible
compilation terminated due to -Wfatal-errors.
But the variable i is public in the class A. What am I doing wrong?
You're inheriting A privately:
class B : A {
^^^^^^
You need to inherit A publicly:
class B : public A {
^^^^^^^^^^^^^
Related
This question already has answers here:
How does virtual inheritance actually work?
(1 answer)
Internal mechanism of virtual inheritance
(1 answer)
How does virtual inheritance solve the "diamond" (multiple inheritance) ambiguity?
(5 answers)
How C++ virtual inheritance is implemented in compilers?
(5 answers)
Closed 11 months ago.
Consider the following code:-
#include<iostream>
using namespace std;
class A
{
public:
int a;
A()
{
a = 10;
cout<<"Address of a in A "<<&a<<endl;
}
};
class B : public virtual A {
public:
B()
{
cout<<"Address of a in B "<<&a<<endl;
}
};
class C : public virtual A {
public:
C()
{
cout<<"Address of a in C "<<&a<<endl;
}
};
class D : public B, public C {
public:
D()
{
cout<<"Address of a in D "<<&a<<endl;
}
};
int main()
{
A a;
B b;
C c;
D d;
return 0;
}
So, here when we create an object of D class, Constructors are called in this order A()->B()->C()->D().
Here A() is not called again before C() because we had made use of virtual keyword, which is preventing the constructor A() to be called again.
** Question: 1 But, I wanted to know what is happening in background in code when we are using the virtual keyword?
Question 2 And is variable a in class A and class B point to same memory location?
Question 3 And why this variable's memroy address differs in class C when A is not made virtual from the address of that variable in B?**
This question already has answers here:
Using C++ base class constructors?
(6 answers)
Closed 1 year ago.
class A {
public:
int _a
A(int a) : _a { a} { }
};
class B : public A { }
Why can't I initialize a variable of A type with using the inherited constructor?
B a(5);
Error: "No matching constructor for initialization of 'B'"
Because B doesn't have such a constructor taking int by default, unless inherit it explicitly:
class B : public A {
using A::A; // inheriting constructor
};
This question already has answers here:
Virtual Inheritance: Error: no unique final overrider
(2 answers)
Multiple (diamond) inheritance compiles without "virtual", but doesn't with
(2 answers)
Closed 6 years ago.
I have this part of code
#include <iostream>
using namespace std;
class A {
public:
int i;
A(){i = 0; }
virtual void f() { cout << i; }
};
class B1 : virtual public A {
public:
B1() { f(); }
void f() { cout << i+10; }
};
class B2 : virtual public A {
public:
B2() { f(); }
void f() { cout << i+1; }
};
class C : public B1, public B2 {
public:
C() {}
};
void main(){
C c;
//c.A::f();
}
First, I understand the main idea behind using virtual inheritance (diamond) in order to create only one A object in memory.
In this example, I get compilation error in C class:
override of virtual function "A::f" is ambiguous
If I remove the virtual inheritance. The code compiles, there is no error in class C as before.
If I remove the comment from the last code line it still compiles. I understand that in this case the f() function that will be executed is the one from the first class that C inherits from.
Now, if I replace c.A::f() with c.f() I get a compilation error at this specific line.
Can someone please explain this behaviour and the differences between these cases?
The problem is with C not with your expression call. As f is virtual and redefined twice in B1 and B2 then the C class is malformed because a call to fwould be ambiguous (which override to choose?). Add an override of f in Cand everything will be ok.
Within the class C you must choose which variant of f to usr. That is, using B1::f; or using B2::f.
This question already has answers here:
Accessing protected members in a derived class
(8 answers)
Closed 6 years ago.
class B
{
protected:
int x;
public:
B(int i=28) { x=i; }
virtual B f(B ob) { return x+ob.x+1; }
void afisare(){ cout<<x; }
};
class D: public B
{
public:
D(int i=-32):B(i) {}
B f(B ob) { return x+ob.x-1; }
};
void test6()
{
B *p1=new D, *p2=new B, *p3=new B(p1->f(*p2));
p3->afisare();
}
The main just calls the function test6();
My question is, why does the compiler throw an error on the 3rd line, at
int x declaration, with the message :
In member function 'virtual B D::f(B)' :
error: 'int B::x' is protected
error: within this context
PS : The example is from an exam so the faulty indentation and other "leaks" are intentionally.
D can access B's member x but only the one it inherits. It cannot access member x of another instance of B.
EDIT: Corrected the answer.
This question already has answers here:
Accessing inherited variable from templated parent class [duplicate]
(2 answers)
Closed 7 years ago.
I want to access protected variable in parent class, I have the following code and it compiles fine:
class Base
{
protected:
int a;
};
class Child : protected Base
{
public:
int b;
void foo(){
b = a;
}
};
int main() {
Child c;
c.foo();
}
Ok, now I want to make everything templated. I changed code to the following
template<typename T>
class Base
{
protected:
int a;
};
template <typename T>
class Child : protected Base<T>
{
public:
int b;
void foo(){
b = a;
}
};
int main() {
Child<int> c;
c.foo();
}
And got error:
test.cpp: In member function ‘void Child<T>::foo()’:
test.cpp:14:17: error: ‘a’ was not declared in this scope
b = a;
^
Is it correct behavior? What's the difference?
I use g++ 4.9.1
Hehe, my favourite C++ oddity!
This will work:
void foo()
{
b = this->a;
// ^^^^^^
}
Unqualified lookup doesn't work here because the base is a template. That's just the way it is, and comes down to highly technical details about how C++ programs are translated.