class A
{
class B
{
int x;
}
public:
void printX() { std::cout << ????; }
}
How can I access the x variable from the A class function? I can't make it static either...
I tried everything but it either tells me I need an object in order to access it or the compiler doesn't find the function.
it either tells me I need an object [...]
Think about that. Because that's exactly what the problem is here.
If you instantiate an A, you don't also get a B. A nested class isn't a member variable of the enclosing class. It's really just another way to change the namespace of a class.
So, you need an instance of B. Perhaps a member of A?
class A
{
class B
{
public:
int x;
} mB;
public:
void printX() { std::cout << mB.x; }
};
You don't ever declare an instance of the class B inside A. You need to do something like this:
class A
{
class B
{
public:
int x;
};
B b;
public:
void printX() { std::cout << b.x; }
};
You don't. You do need an object in order to use the x variable. You could, however make it static. The problem with your example is x is not public. Placing B inside A does not make B part of A, it only changes B's scope.
From this example it kinda looks like you're after inheritance instead. This would give you the effect you're after ( access to all B's methods and variables without making an object. )
Class B
{
protected:
int x;
}
Class A : B
{
void printX() { std::cout << x; }
}
Related
Sorry if this has been asked before; I found similarly titled questions, but none of them focused on the same aspects I'm having trouble with.
There's a class A, and a class B that should only be accessible from A. I think nesting B inside A will achieve that, but I'm struggling with the logistics.
A has a B as a member. As such, not defining B prior to declaring A's members causes incomplete type errors. I thought I'd get around this by declaring A, defining A::B, then defining A, but that just throws the same errors plus incomplete type 'A' in nested name specifier.
class A;
class A::B
{
...
};
class A
{
private:
class B;
B b;
...
};
The only functional examples I can find would put B's member declaration directly inside A's, which I'd really like to avoid doing: B's header information is several times longer and much denser than A's. Splitting the two up into separate files would be best, but actually nesting them inline is incredibly unwieldy.
Fallback options at this point include making A's B a pointer (no real reason why not, but is this really something that can't be done?) and leaving them as independent classes. But surely this can't be that hard?
What do I need to declare to link these properly and in what order?
I am not particularly knowledgeable about the depths of C++ so please explain like I'm five and refrain from shaming me into the ground for not knowing everything.
Since b is a non-reference non static data member of class A, it must be declared to have a complete type.
One way to solve this would be to either make b a reference type(as shown below) or a pointer to a B:
class A
{
private:
class B;
//--vv------------>now b is an lvalue reference to a B object
B& b;
};
class A::B
{
};
Method 2
Other option is to define B inside A with only its member declaration and then define those members outside as shown below:
class A
{
private:
//defined class now
class B
{
void member1();
};
B b; //works now
};
void A::B::member1()
{
}
One particularly non-convoluted way of doing this would be
class B
{
friend class A;
private:
// everything;
};
class A
{
B b;
};
This of course makes all the guts of B accessible to A, bit if B is such A-specific, it should not be a problem.
If this is not desirable, a slightly wore windy path to a solution would be
class PreA
{
protected:
class B { ... };
};
class A : PreA
{
B b;
};
The only functional examples I can find would put B's member
declaration directly inside A's, which I'd really like to avoid doing:
B's header information is several times longer and much denser than
A's. Splitting the two up into separate files would be best, but
actually nesting them inline is incredibly unwieldy.
The premise is interesting until I saw this comment of yours, I assume by you mean "Hide" is "Hide the Code it Self", not the members and method of B?
B is already tailored to the specifics of A and wouldn't be reusable
without modification. That's really why I want to hide it.
And with this line, can I assume that you aren't familiar with the concept of inheritance?
I am not particularly knowledgeable about the depths of C++ so please
explain like I'm five and refrain from shaming me into the ground for
not knowing everything.
You can simply inherit Class A into Class B, then use Class B itself? or the other way around. Just remember that the Base Class [Class A in this Case] has no idea what methods or member the Derived Class has [Class B in this Case].
e.g.All (Derived)Airplanes can (Base)Fly but not everything that can Fly is an airplane.
A Little Introduction to Inheritance can be found here. and if you do decide to go through this route, please Read up on a lot of materials about it. It's a Deep hole.
class A
{
public:
A()
{
x=0;
y=0;
std::cout << "A's Default Constructor Used " << std::endl;
}
virtual ~A(){std::cout<<"A's Destructor called" << std::endl;};
int x;
int y;
};
class B : public A
{
public:
B(){}
B(int nX, int nY){x=nX,y=nY;}
~B(){std::cout<<"B's Destructor Called"<<std::endl;}
public:
void SomeMethod(int nX){x+=nX;}
};
int main() {
B b;
std::cout << b.x << " " << b.y << std::endl;
b.SomeMethod(10);
std::cout << b.x << " " << b.y << std::endl;
}
NOTE: On A's destructor [virtual ~A(){std::cout<<"A's Destructor called" << std::endl;};] the keyword virtual is not needed unless you are deleting / destroying Class B from a Pointer to an Object of Class A, and Absolutely necessary if you are, Like Below.
B* b = new B;
std::cout << b->x << " " << b->y << std::endl;
b->SomeMethod(10);
std::cout << b->x << " " << b->y << std::endl;
A* a = b;
delete a;
Without the virtual keyword, only A's Destructor would be called and not B's.
Unless inheritance is out of the question then Nesting(Which I personally don't recommend it's a big pain on maintenance) ,creating a pointer of Class B inside A.
Or simply create Class B inside Class A like below.
class B
{
public:
B()
{
z = 0;
std::cout<<"B Default Constructor Used"<<std::endl;
}
B(int nZ)
{
z = nZ;
std::cout<<"B Constructed"<<std::endl;
}
~B(){}
public:
void SomeMethod(int& nX,int nY){nX += ( nY + z );}
int z;
};
class A
{
public:
A()
{
x=0;
y=0;
std::cout << "A Default constructor used" << std::endl;
}
A(int nX,int nY,int nZ)
{
x = nX;
y = nY;
b.z = nZ;
std::cout << "A's Constructed" << std::endl;
}
~A(){};
B b;
int x;
int y;
};
int main() {
A a;
a.b.SomeMethod(a.x,10);
std::cout << a.x << std::endl << std::endl;
// Ore something like this;
A a2 = A(1,2,3);
a2.b.SomeMethod(a2.x,20);
std::cout << a2.x << std::endl;
}
Just remember to create a Default Constructor for Class B since it would be called during the creation of Class B. Take note that I am speaking from my personal Experience and Knowledge, and by no means is it gospel, specially when I am self taught, and Using conventions that I am using in my own projects.
Declaring a Class static is one way to prevent Class B's Creation as Well but able to use it's functions . But I rarely find the need to do this in productions. I've mainly used this in debugging things. Since I've only seen it used in C#, and I've never tried it using it in production since I don't know what kind of behavior it could produce.
#include <iostream>
static struct B
{
protected:
B(){};
public:
static void PrintSomething(int x)
{
std::cout <<"Printing Something " << x <<std::endl;
}
static void MultiplyBy2(int* x)
{
int Two = 2;
*x = *x * Two;
}
};
class A
{
public:
A(int nX,int nY):X(nX),Y(nY){}
public:
int GetX()const{return X;}
int GetY()const{return Y;}
int* PointerToX() {return &X;}
private:
int X;
int Y;
};
int main()
{
A a(1,2);
B::PrintSomething(a.GetX());
B::MultiplyBy2(a.PointerToX());
B::PrintSomething(a.GetX());
B::MultiplyBy2(a.PointerToX());
B::PrintSomething(a.GetX());
return 0;
}
The goal of the code structure below is to be able to store pointers to objects of any class inherited from 'A'.
When I run this code, I get 0 written out, but what I'm trying to access is the 'B' object's 'num' value, which is 1. How can I do that?
As far as I know, when you create an inherited class's object, you create an object of the parent class too automatically. So can I somehow access the parent class object from it's child and set it's class member to match?
See minimal reproducible example below.
Update: Virtual functions solved the problem.
#include <iostream>
class A
{
public:
int num;
A()
{
num = 0;
}
};
class B : public A
{
public:
int num;
B()
{
num = 1;
}
};
class C
{
public:
A* ptr_array[2];
C()
{
ptr_array[0] = new B();
}
void print()
{
std::cout << ptr_array[0]->num << std::endl;
}
};
int main()
{
C* object_c = new C();
object_c->print();
return 0;
}
The problem is that you define a member num in A, and another member num in B. So an object of type B has two members called num, and you're leaving it to the compiler to choose which one to use -- which it does, according to logical rules which may be unfamiliar to you.
If you remove the line in num; from the definition of B, the code will work as you intend.
Your array is a red herring. You are only using one pointer. Might just as well have it as a member for the sake of the example.
I suppose you might need something like this (note, untested code).
#include <memory>
#include <iostream>
class A {
public:
A() : m_num(0) {} // use this instead of assignment in the c'tor body
virtual int getNum() { return m_num; } // this is **the** way to use inheritance
virtual ~A() = default; // required
private:
int m_num;
};
class B : public A {
public:
B() : m_otherNum(1) {}
virtual int getNum() { return m_otherNum; } // does something different from A
private:
int m_otherNum; // you could also call it m_num, but for clarity I use a different name
};
class C {
public:
C() : m_a (std::make_unique<B>()) {} // note, use this instead of new B
void print() {
std::cout << m_a->getNum() << std::endl;
}
private:
std::unique_ptr<A> m_a; // note, use this instead of A* m_a;
};
I have no way of knowing if this is really what you need (or you think you need). This is how inheritance is supposed to be used in object-oriented programming. You can use it in various other ways and produce correct (as far as the language definition is concerned) programs. But if this is the case, then (public) inheritance is likely not the best tool for the job.
I have two classes like this:
#include <iostream>
class A {
public:
class B {
public:
void printX(void) const { std::cout << A::x << std::endl; }
};
private:
int x;
};
Obviously this piece of code doesn't work because B can't access x, but is there a way to make it work?
I've tried using friend class keyword in both classes like this:
class A {
public:
class B {
public:
friend class A;
void printX(void) const { std::cout << A::x << std::endl; }
};
friend class B;
private:
int x;
};
But it didn't work either, and I can't figure out if it's even possible.
According to the C++ 17 Standard (14.7 Nested classes)
1 A nested class is a member and as such has the same access rights as
any other member. The members of an enclosing class have no special
access to members of a nested class; the usual access rules (Clause
14) shall be obeyed.
The problem with the provided code is that x is not a static data member of the class A. You need to provide an object of the class A the data member x of which will be accessed within an object of the nested class.
For example
class A {
public:
class B {
public:
void printX( const A &a ) const { std::cout << a.x << std::endl; }
};
private:
int x;
};
A::B().printX( A() );
As the error message should tell you, A::x isn’t a static member so you need an object instance to access it. If you add a reference to instance of A to B::A, you can use that to access A::x.
For example, the following works:
class A {
public:
class B {
public:
B(A const& a) : a(a) {}
void printX(void) const { std::cout << a.x << std::endl; }
private:
A const& a;
};
private:
int x;
};
Note that using a reference member has several implications. Notably, you can now no longer reassign instances of type A::B, nor are its instances movable. As a consequence, it’s often convenient to hold a pointer rather than a reference to A inside A::B. Either way, you’ll need to ensure that instances of A::B do not outlive the A instance they refer to, otherwise you end up with a dangling reference.
I'm trying to set the value of a member of a class from another class using this snippet. Here is a sample of the code I'm trying to make work
class A
{
private:
int a;
public:
A()
{
a = 0;
}
A(int val)
{
a = val;
}
int GetA()
{
return a;
}
void SetA()
{
a = 290;
}
};
class B
{
B(){};
void SetB()
{
A a;
a.SetA();
}
};
int main(){
A a;
B b;
b.SetB();
cout << b.GetA();
}
How can I make this code pint out 290.I currently prints out 0
In SetB your A variable is a temporary that is destroyed when the function returns.
The way it is written in your snippet, your code won't compile, because B has no method GetA(). From your use case (the code in main()), I suspect you either want B to inherit from A:
class B : public A
{
public:
B() {];
void SetB()
{
SetA();
}
};
although that doesn't make too much sense, because in this case you could just call b.SetA() directly. Or, you want an object of type A as a member of B:
class B
{
public:
void SetB()
{
a.SetA();
}
int GetA()
{
return a.GetA();
}
private:
A a;
};
But it's a bit hard to tell from your snippet what you're actually trying to achieve.
Also, you probably want your Get…() methods to be const.
If you;re trying to achieve what I think you're trying to achieve then you're nearly there, it is just that you are creating two versions of A, one on the main stack, and one that is a temporary inside B::SetA()
try passing A as a reference parameter to B, so that there is only one version of A.
void SetB(A& a)
{
a.SetA();
}
then your calling code would be:
A a;
B b;
b.SetB(a);
cout << a.GetA();
Alternatively, pass a in the constructor of B and store A as a reference member in B;
#include <string>
#include <iostream>
class a { public: int x;};
class b : public a {public: int x; } ;
int main()
{
b bee;
bee.x = 3;
a ay = bee;
std::cout << std::endl << ay.x << std::endl;
}
The code above compiles fine in clang 3.0 and g++ 4.5. However the output is junk (--i.e., not three). Since the compiler doesn't seem to mind, how do I get the code to behave ?
Secondly, If there is some way to make the above slice / conversion to work correctly, how bad would it be if I then did the following, provided a good reason to do it exists :
class c : public a { public: uint64_t x; };
Why I am interested in these semantics.
The reason I want to do this is this. I have a two class heirachies, where one heirarchy (the parent) aggregages objects, on the same heirarchy level, from the other(the child). I use a custom container for the aggregation. I want to typedef the container in the parent class (the typedefs have the same name), and declare the container with the same name at each level of the parent.
The class heirarchies are designed to contain less information at lower levels ( the base classes hold the least), therefore slicing makes perfect sense here.
Edit:
There you go, this should clear things up.
class A { int x; };
class B : public A {int y;};
class Ap {std::vector<A> entries;};
class Bp : Ap{std::vector<B> entries;};
The child B has more members than the child class A. However, I wan't to present a uniform interface for code that is only interested in the members of class A.
There is no way to do that if you directly set b::x. a::x and b::x are two different members, and the latter hides the former.
You can still access a::x on an object of type b with static_cast<a&>(bee).x = 3, but the fundamental problem is that the values of a::x and b::x on an object of type b are not synchronized.
If you abstract access to both x members with a "property getter/setter", then you can arrange for the setter on the derived class to also update the member of the base class. Or (maybe this is more appropriate?) you can make the member of the base class protected and use it from the derived class directly, slicing as you need just before returning from the getter.
huh ! its a bit complicated no ?
why don't you use :
class a
{
virtual void set( int value ) { x = value; }
protected :
int x;
};
class b : public a
{
virtual void setA( int value ) { a::x = value; }
or
virtual void setA( int value ) { b::x = value; }
or
virtual void setA( int value ) { a::x = value; b::x = value; }
protected:
int x;
} ;
There are two ways of constructing a software design; one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.
C.A.R.Hoare
According to Jon's answer, Since a::x and b::x are separate variables, furthermore since b::x masks a::x, if you wanted to get the correct semantics you need to provide a copy conversion constructor. The following code does the trick.
#include <string>
#include <iostream>
class b;
class a {
public:
a();
a(const b & bee);
int x;
};
class b : public a {public: int x; } ;
a::a() {}
a::a(const b & bee)
{
x = bee.x;
}
int main()
{
b bee;
bee.x = 3;
a ay = bee;
std::cout << std::endl << ay.x << std::endl;
}
Maybe try something like this:
class A { int x; };
class B : public A {int y;};
class Ap {
public:
void Append(A *pa)
{
entries.push_back(pa);
}
A *GetA(size_t nIndex)
{
return entries.at(nIndex);
}
private:
std::vector<*A> entries;
};
class Bp : Ap
{
public:
B *GetB(size_t nIndex)
{
return dynamic_cast<B*>(GetA(nIndex));
}
};