method of a pointer pointing to an object is inaccesible - c++

my class looks like this
class A{
private:
int id;
public:
A();
int getId();
}
class B{
private:
public:
B();
}
Implementation
//constructor
B::B() : A(){
}
B extends A class.
Okay in my main cpp I have a function like this
bool checkID(B *obj){
if(obj->getId() > 1){ return true; } else { return false; }
}
However, the obj->getId() , getId() says its inaccesible.
Why is it?

By default C++ uses private inheritance. Use B : public A to publicly inherit from A. Also you need to define the inheritance in the declaration.
class B : public A {
public:
B();
}

B must derive from A to have A's members be accessible from B objects.
class B : public A { ... };

Related

why am i getting error while inheriting template class [duplicate]

How can I access base class variable from a child method? I'm getting a segmentation fault.
class Base
{
public:
Base();
int a;
};
class Child : public Base
{
public:
void foo();
};
Child::Child() :Base(){
void Child::foo(){
int b = a; //here throws segmentation fault
}
And in another class:
Child *child = new Child();
child->foo();
It's not good practice to make a class variable public. If you want to access a from Child you should have something like this:
class Base {
public:
Base(): a(0) {}
virtual ~Base() {}
protected:
int a;
};
class Child: public Base {
public:
Child(): Base(), b(0) {}
void foo();
private:
int b;
};
void Child::foo() {
b = Base::a; // Access variable 'a' from parent
}
I wouldn't access a directly either. It would be better if you make a public or protected getter method for a.
Solved! the problem was that I was calling Child::foo() (by a signal&slot connection) from a non yet existing object.
Thanks for the aswers.
class Base
{
public:
int a;
};
class Child : public Base
{
int b;
void foo(){
b = a;
}
};
I doubt if your code even compiled!

c++ Getting access to member outside from inheritance chain

I have the following design:
- one class A that has a protected member of class M.
- one class B that inherits from A and has a pointer to an object of class C
- one class C that needs to have access to the member of the class A
class A {
public:
A() : _member(0) {}
~A() { delete _member }
protected:
M _member;
}
class B : public A {
public:
B(){}
~B(){}
protected:
C* c;
}
class C {
// C needs to have access to _member
}
What design should be more appropriate to solve this issue ?
In pure OO terms, allowing a class to directly access the internal fields of another class is bad practice.
That said, C++ is not a pure OO language, and does allow for this (among other important deviations from OO).
To allow access to a private member to another class, you must designate that class to be a friend. Friendship, however is not passed to derived classes, therefore you must upcast the class to the type you need.
This is your simplest solution:
class A {
public:
A() : _member(0) {}
~A() { delete _member }
protected:
friend class C;
M _member;
}
class B : public A {
public:
B(){ c = new C(this); } // this call will cast the B* to an A* (important)
~B(){ delete c;}
protected:
C* c;
}
class C {
public:
C(A* a) { _a->_member = new M(); } //Now C can directly access _member in A
}
In such a way, any object derived from A can be turned back into an A* and used to access _member.
However, as previously stated, any classes derived from C will not gain access to _member, as friendship is not inherited, so a more comprehensive solution is required:
class M {
public:
void Foo() { printf("Foo called\n"); }
};
class A {
M* m;
friend class C;
public:
A():m(0) { ; }
};
class B :public A {
int id;
public:
B() { id = 0; }
};
class C {
public:
C() { _a = 0; }
C(A* a) { _a = a; }
protected:
M* getM() { return _a->m; }
void setM(M* m_) { _a->m = m_; }
private:
A* _a;
};
class D : public C {
public:
D(B* b): C(b) {
}
void Foo() {
setM(new M());
getM()->Foo();
delete getM();
setM(nullptr);
}
};
int main()
{
B* b = new B();
D d(b);
d.Foo();
delete b;
getchar();
return 0;
}
In this way, no classes derived from A provide direct access to _member, and no classes derived from C have direct access, but the member variable can still be accessed via C's protected API. This also prevents other external objects accessing it.
Make C a friend of A:
class A {
friend class C;
/*and so on*/
Then C can see all member variables and functions in A, even if they are private.

How to access private members of an abstract class from its friend class?

class A
{
private:
int a,b,c;
public:
virtual int get()=0;
friend class B;
};
class B{
//here I want to access private variables of class A that is a, b and c
};
class C:public class A
{
int get(){
//some code
}
};
How to access private members of class A in class B. I cannot create an object of class A since it is abstract. I somehow have to use an object of class C to do that but how?
class A {
friend class B;
private:
int x;
public:
A() : x(42) {}
};
class C : public A {
};
class B {
public:
int reveal_secrets(C &instance){
// access private member
return instance.x;
}
int reveal_secrets(){
// access private member of instance created inside B
C instance;
return instance.x;
}
};
void print_secrets(){
C instance;
B accessor;
std::cout << accessor.reveal_secrets(instance) << ", " << accessor.reveal_secrets() << std::endl;
}
class B will have to have an instance object to work with in the first place. That instance object is what B will look at in order to access a, b, etc .

Override method in multi inherite C++

I see this problem in C++.
class A{
public:
char* getName(){ return "A";}
void showData(){
cout<<"A";
}
};
class B:public A{
public:
void showData(){
A::showData();
cout<<"B";
}
};
class C:public A{
public:
void ShowData(){
A::showData();
cout<<"C";
}
};
class D:public B,public C{
public:
void showData(){
B::showData();
C::showData();
cout<<"D";
}
};
Problem1:
D* d=new D();
d->showData(); // I want it prints "ABCD" but it prints "ABACD"
Problem2:
cout<< d->getName(); // it shows error: ambiguous access of 'getName'
Can you help me solve 2 problems?
Thanks.
Problem 2 is happening because your class D contains two copies of the base class A. When you call d->getName(), the compiler does not know which one to pick up. To fix this, use virtual inheritance.
Simply put, derive your class A virtually in both classes B and C:
class A { ... }
class B : public virtual A { ... }
class C : public virtual A { ... }
class D : public B, public C { ... }
This guarantees a single embedded copy of class A in class D and will solve the ambiguous access error.
As for problem 1, virtual inheritance will be a good start, but you will need to find some way to rework your logic so that A::getName() is not called twice when you call D::getName().

derive problem about c++

Why I can't access base class A's a member in class B initialization list?
class A
{
public:
explicit A(int a1):a(a1)
{
}
explicit A()
{
}
public:
int a;
public:
virtual int GetA()
{
return a;
}
};
class B : public A
{
public:
explicit B(int a1):a(a1) // wrong!, I have to write a = a1 in {}. or use A(a1)
{
}
int GetA()
{
return a+1;
}
};
class C : public A
{
public:
explicit C(int a1):a(a1)
{
}
int GetA()
{
return a-1;
}
};
A's constructor runs before B's, and, implicitly or explicitly, the former construct all of A's instance, including the a member. Therefore B cannot use a constructor on a, because that field is already constructed. The notation you're trying to use indicates exactly to use a constructor on a, and at that point it's just impossible.
To build on Alex' answer, you can initialize the base class' "a" member by controlling its construction, like so:
class B : public A
{
public:
explicit B(int a1) : A(a1) { } // This initializes your inherited "a"
...
};
Note that I'm constructing the base class (capital "A") above, rather than attempting to directly initialize its inherited member (lowercase "a", drawing from your example).
To build even further on pilcrow's answer, you could easily initialize the A member like you want by overriding it in your B class:
class B : public A
{
public:
int a; // override a
explicit B(int a1) : a(a1) // works now
{
}
...
};
Though, I wouldn't necessarily recommend this ;)