Virtual function triggers compilation error on protected variable [duplicate] - c++

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.

Related

how to initialize base class with members of derived class [duplicate]

This question already has answers here:
warning: derived class's member variable is initialized after base class
(3 answers)
C++: Construction and initialization order guarantees
(5 answers)
Closed 9 months ago.
Beginner here, my simplified code:
A.h
class A{
public:
A(int x);
private:
int _x;
}
A.cpp
A::A(int x)
: _x(x)
{
}
B.h
class B : public A{
public:
B()
private:
int _y = 1;
}
B.cpp
B::B()
: A(1) //works
: A(_y) //doesn't work
{
}
Why does the initialization with a member of B not work, but with a bare integer it does.
I mean I can just go for the working method but I'd like to know the cause.
Thanks for any helpers!:)
Vlad has given you the reason, here's a workaround that avoids the need to duplicate your magic number:
class B : public A{
public:
B();
private:
static const int initial_y = 1;
int _y = initial_y;
};
B::B()
: A(initial_y)
{
}
Demo
A derived class's base classes are fully initialized before any of the derived class's data members are initialized.
In the case of:
class B : public A{
public:
B();
private:
int _y = 1;
}
B::B()
: A(_y)
{
}
Data members that have initial values in their declarations are implicitly handled by the constructor's member initialization list. So, in this case, the compiler treats the above code as-if you had written it like this instead:
class B : public A{
public:
B();
private:
int _y;
}
B::B()
: A(_y), _y(1)
{
}
As you can see, A(_y) is called before _y is initialized, which is undefined behavior.

Virtual Base Class and Diamond Problem in C++ [duplicate]

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?**

Initialize base class with data member from derived class [duplicate]

This question already has answers here:
Order of calling constructors/destructors in inheritance
(6 answers)
Closed 5 years ago.
Consider a code
struct X {
X (int n) {...}
};
struct Base {
Base(X & x) {...}
};
struct Derived : public Base {
Derived() : Base(x), x(2) {}
X x;
};
Code works and i see no issue there but i'm concerned about the look of : Base(x), x(2) statement. First pass the instance to Base and after you initialize the actual object. Is this the the only way to express the intention?
The trick is to derived from one more base class who's function is to own the X.
Note that base class declaration order matters:
struct X {
X (int n) {}
};
struct Base {
Base(X & x) {}
};
struct OwnsAnX {
OwnsAnX(int n) : x_(n) {}
X& get_x() { return x_; }
private:
X x_;
};
struct Derived
: OwnsAnX // note: order is important
, Base
{
Derived()
: OwnsAnX(2)
, Base(get_x())
{}
// x is accessed through the inherited get_x()
};
but it's error prone if you don't keep the correct order of the classes you're inheriting from
This is a valid concern of the OP. The solution is to enable the compiler warning -Wreorder.
Reversing the order of the base classes then yields:
<source>: In constructor 'Derived::Derived()':
<source>:24:23: warning: base 'OwnsAnX' will be initialized after [-Wreorder]
, Base(get_x())
^
<source>:24:23: warning: base 'Base' [-Wreorder]
<source>:22:9: warning: when initialized here [-Wreorder]
Derived()
^~~~~~~

calling a member function of a class by member function of another class? [duplicate]

This question already has answers here:
calling a member function of different class from another class
(2 answers)
calling a class method from another class
(1 answer)
Closed 7 years ago.
i have two classes A & B.i want to call a member function of A by member function of B.
class A {
public:
void memberofa();
}
class b:
class B {
public:
void memberofb();
}
now i need to call memberofa from inside memberofb.
Any suggestions and syntaxes will be helpful
Something like this?
class A {
public:
A() {};
void memberofa()
{
//you cant make object of B here because compiler doesn't see B yet
//if you do want to make Object of B here, define this function somewhere
//after definition of B class
printf("printing from member of A\n");
};
};
class B {
public:
B() {};
void memberofb()
{
printf("printing from member of B\n");
A objA;
objA.memberofa();
};
};
int main()
{
A a;
B b;
b.memberofb();
return 0;
}
B inherit from A
B contain A object
A::memberofa is static function
A is singleton class
A inherit from B, B has memberofa and it is virtual function.

Overloaded final function in derived class [duplicate]

This question already has answers here:
Why does an overridden function in the derived class hide other overloads of the base class?
(4 answers)
Closed 8 years ago.
How can I use final overloaded function from derived class?
Compiler says 'no matching function for call to 'B::foo()''.
class A
{
public:
virtual void foo() final
{
std::cout << "foo";
}
virtual void foo(int b) = 0;
};
class B : public A
{
public:
void foo(int b) override
{
std::cout << b;
}
};
//Somewhere
B* b = new B;
b->foo(); //Error
But it works without overloading.
class A
{
public:
virtual void foo() final
{
std::cout << "foo";
}
};
class B : public A
{
};
//Somewhere
B* b = new B;
b->foo(); //Works!
This declaration in class B
void foo(int b) override
{
std::cout << b;
}
hides all other functions with the same name declared in class A (excluding of course the overriden function).
You can either call the function explicitly like this
b->A::foo();
Or include using declaration
using A::foo;
in the definition of class B.
Or you can cast the pointer to the base class pointer
static_cast<A *>( b )->foo();