C++ nested classes, access fathers variables [duplicate] - c++

This question already has answers here:
Can inner classes access private variables?
(5 answers)
Closed 6 years ago.
The title already says a lot,
but basically what i want to do is the following(Example):
I have a class called A, and another class inside a called B, like so:
class A
{
int a;
class B
{
void test()
{
a = 20;
}
};
};
As you can see my goal is for class B to have access to class A, as it is a nested class. Not this wont work, because B doesn't have access to A, but how can it get access?
Thank You

Despite that you declared class B inside of A, classes A and B are still completely independent. The only difference is that now to refer to B, one must do A::B.
For B to access A's stuff, you should use composition or inheritance. For composition, give B a reference to an object of A, like so:
class B {
public:
B(const A& aObj) : aRef(aObj) {
cout << aRef.a << endl;
}
private:
const A& aRef;
};
For inheritance, something like this:
class B: public A { // or private, depending on your desires
B() {
cout << a << endl;
}
}

The inner class is not related to the outer class in C++ as it is in Java. For an instance of A::B to access a member of an A object, it needs to have an instance of A somewhere, just as if B were not a nested class. Instances of A::B do not have any implicit instance of A; you can have many instances of A::B without any instances of A existing at all.
Pass an instance of A to test, and then use it to access the a member:
void test(A& a_instance)
{
a_instance.a = 20;
}

Classes are types, types don't have data. Instances have data, but an instance of A does not (in your example) contain an instance of B, and the instances of B don't have any knowledge of any instance of A.

Choices
have B be a child of A instead of contained by A
have B's constructor take a ref to the A instance which created it (preferred)
Now, if the variable a is private this still won't help. You will either need an accessor a or a friend relation.

C++ nested classes are not like java nested classes, they do not belong to an instance of A but are static. So a doesn't exist at that point

Related

Overriding virtual method inside another class to access its member in c++

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().

How to access the overidden function of an object of type subclass which is in a vector with a template of class [duplicate]

This question already has answers here:
What is object slicing?
(18 answers)
Closed 4 years ago.
I have a class A, which defines an empty function foo, among other things.
Two subclasses inherit from A, AA and AB. Both of these override foo in different ways.
A separate class, C, needs to hold different instances of the subclasses, so I have defined a vector with a template of class A within it. The issue is, when I try to run foo by accessing the subclass from the vector in C, it runs the empty version of foo in A, rather than the overridden version from AA or AB.
How can I have a vector in C which can hold different instances of the subclasses and be able to run the overridden version of foo?
If you'd prefer to see the classes in code -
A
class A
{
public:
A();
foo() {}
};
AA
class AA : public A
{
public:
AA();
foo() { //does something else }
};
AB
class AB : public A
{
public:
AB();
foo() { //does a different something else }
};
C
class C
{
public:
C();
private:
std::vector<A> things;
};
From within C, if I try to run things.at(x).foo() it calls the foo from A, but I need to call the foo from the correct subclass.
Thanks for any advice you can give!
You need to mark your base class functions as virtual. By default c++ methods are non-virtual so all your instances of foo() are completely separate methods which just happen to have the same name.
If you are using a modern compiler you should also mark your derived methods with override to get the compiler to check for you that you really are overriding a base class method.
You also can't store the objects by value in the vector, you need to store pointers, references, unique_ptr or shared_ptrs instead. If you store by value when you add an object to the vector it will be copied into a new object of type A

Does the code get copied to derived class?

Whenever I derive a new class from base class say:
#include <iostream>
class A {
protected:
int f;
public:
void get() {
std::cout << "The address is: "
<< &f << std::endl;
}
};
class B : public A {
// ....
};
int main() {
A a;
a.get();
B b;
b.get();
return 0;
}
The address is: 0xbfb0d5b8
The address is: 0xbfb0d5bc
Does this means that all the code from class A will be copied to class B? Since I have nothing in class B i.e. no data members or functions So, when I create an instance of class B, then I find that it has its own variable at different address and it also has a member function. How can it have its own of copy members if it they aren't copied?
Is that what do we mean by code reuse in inheritance?
Edit:
Updated my code to reflect what I meant by copying of variables.
Code is never copied during inheritance. But when the child object (class B) is created or instantiated at run time, it inherits the functionality and attributes of the parent class/object (class A).
the code from class A does NOT copied to class B in the sense that there is only one place the code is written.
however, and here cones the Reusable part, when using class b u can call the method and use the members, with respect to private, public, etd and thus does not have to write the same code for two class that do the same thing
for example if i have a circle and a square, and they both have a member called color that i want a method that change it, i do not need to write the method and the member twice, but have them inherit class Shape that will implement it once and then they both will be able to use that method, thus reusing one method in two places
I'm not sure "copied" is the right word (the compiler will only compile the code in class A once). As you have used public inheritance, class B actually is a special type of class A. As such, class B does have access to every (non-private) member of class A, so the code is re-used.
In addition, from the conversation in the comments:
No. Nothing is "copied", each instance of A and B has their own value for their own variables, except for any static data members. For static data members, again there is no copying going on; there is simply only one variable and that is shared by all instantiations of A and B.
In your example, you are comparing two different instances of two different classes. different instances means different base addresses to store instances data.
Perhaps a better test of whether a field of a class is copied over in derived classes is the following:
#include <iostream>
class A {
protected:
int f;
public:
void get() {
std::cout << "The address is: " << &f << std::endl;
}
};
class B : public A {
// ....
};
int main() {
B b;
b.get();
A *a = &b;
a->get();
return 0;
}
And the output is:
The address is: 0x7fff41d523f0
The address is: 0x7fff41d523f0
With that program, we can see that even though we have an instance of class B, its inherited content is physically the same as the one in the original class A. Note that it is also possible to redefine a class member in a derived class, but the original member will still be available if we coerce an instance of the derived class to the parent class (as I did in my example).
ยง1.8(2) of the C++ language standard defines what is meant by a subobject:
Objects can contain other objects, called subobjects. A subobject can be a member subobject (9.2), a base class subobject (Clause 10), or an array element. An object that is not a subobject of any other object is called a complete object.
These are examples of member subobjects and array elements, which you should be familiar with:
int a[5];
a[2]; // the third array element subobject of the complete object a
struct S { int x; }
S s;
s.x; // a member subobject of the complete object s
That leaves the remaining kind of subobject, the one which you are interested in: base class subobjects.
struct B { int x; }
struct D : public B { int y; }
D d;
d.y; // a member subobject of the complete object d
d.x; // a member subobject of a base class subobject of the complete object d
B &b = d; // a reference to a base class subobject of the complete object d
Every instance of a derived class contains an instance of its base class, as a base class subobject.
I also have some doubts regarding relation between inheritance and code re-use. This is my take on this.
Inheritance is a mechanism used to categorize and facilitate polymorphism. Using inheritance we can build a hierarchy of concepts separated in categories at different levels of abstraction. By doing this, we can efficiently use another OOP concept, polymorphism, which allows the same control code to manage all objects in a category even if they are different in their implementation.
I don't think that we use inheritance for code re-use purpose.

How to access a member variable without instantiation, C++

Suppose I have class B which gets a value 'v' in the constructor from another class A. How can I read this value from class C?
Class C will be instantiated on demand, but A has created B and passed the 'v' already. 'v' will change in every instantiation. I have tried to make 'v' static in Class B. Would it work? I could not implement it properly.
Class A {
public:
int* v;
B b1;
A(int* var) : v(var), b1(var) {};
}
How to access the same version of 'v' from a C class?
I can define B and C however I like in order to achieve the goal. But I cannot change A for that purpose.
You need a (public) static member
class A { //let's stick with your naming convention!
public:
static int a;
}
A::a = 4;
However allowing people to change A::a means that your program will probably end up relying on a global unencapsulated state... which is usually a sign of a bad design.
If you member was const however you are really relating a constant to your class, which is not so bad.
class A {
public:
static const int a = 4;
}
std::cout << "A:a is always " << A::a << std::endl;
EDIT BASED ON UPDATED QUESTION
If you require help with building a class I would recommend that you use a factory of some kind. If I understand your requirement you want to be able to inject a value into every class A and class B instance. This value "v" is based on a Class C.
So...
class C {
private:
// up to you where you implement the getUniqueNumberForNow function
// (global free function for example)
static const int v = getUniqueNumberForNow();
public:
static A createA(){
return A(v);
}
static B createB(){
return B(v);
}
}
The getUniqueNumberForNow() function just gets whatever your value should be. It will be then stored in class C and can be used during the creation of A an\or B. Now just make A and B's CTORs private and make C a friend of both and you will have only one way to create an A or B, and it will always use the correct value.
See NeilMonday's link in the comments below for info on friend classes.
Last thing is if you want to have the value change for every instantiation of A you can just do this in the factory:
static A createA(){
return A(getUniqueNumberForNow());
}
However if that is really what you want then just do this:
class A {
public:
A() : val (getUniqueNumberForNow()), b(B(val)){}
}
You cannot access a 'v' which has never passed to the class. Instead you can make a static copy of it as a member in your class A. It will update every time A is instantiated like this:
Class A {
public:
int* v;
static int* staticv;
...// Constructor etc
}
in your .cc code of A:
int* A::staticv;
...
A::staticv=this->v;
now any class can access to this value by:
A::staticv;

C++ Accessing a private structure from another class

I have a class as shown below:
class B;
class A
{
public:
A();
~A();
void createStuff(.......); //??
private:
B *b;
};
The object B contains another of class 'C' which has about 20 class member variables.
I want the user of class A to be able to call the function createStuff(...) with a set of arguments so that I can construct the object C. What is the best way of doing this?
The mechanism for classes to grant access to their private members is called friendship.
With what you have posted it looks like something like this may work:
class B
class A:
{
public:
A();
~A();
void ceateStuff(.......); //??
private:
B *b
}
void A::createStuff(argument1, argument2...)
{
C = new C(argument1, argument2...) //You now have an instance of C with the arguments pass in to createStuff();
}
The variable of type C belongs to class B; it mediates the access to the data in C. Class B has constructors; you will use those to set the variable of class B in order, and it is B's job to ensure that the C is correctly managed.
If you need more control over C, then you have a design problem. Either your class A needs its own variable of class C to control, or class B does not provide the tools you need and needs fixing, or you are misguided in thinking you need access to, and therefore direct control over, the contents of the variable of class C.
The Law of Demeter is a guide in such scenarios; you seem to be wanting to contravene it.
In any case you should look at B class, how it implement initialization of C object, can it be controlled (If can't - you should extend interface of class B and add this functionality)?
If C definition is accesible for A maybe you can use constructor of B in such way:
void A::createStuff( const C& c)
{
b = new B(c);
}