How to access a member variable without instantiation, C++ - 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;

Related

question with class declaration in c plus plus [duplicate]

I've encountered this code example and I remembered I've seen it before and I didn't know what it is for and what it does? I've searched on the internet but without luck.
Code:
class C
{
int x; // a non-static variable, implicitly private
public:
C() : x(0) {} // default constructor
// a static member function, which uses a non-static variable perfectly well
static int Incr(C& instance) { return ++(instance.x); }
} g_c;
int main(void)
{
C c2;
return C::Incr(g_c) + C::Incr(c2);
}
What does g_c after the last class bracket means?
} g_c;
Here g_c is declared to be an object of the class type C.
Such construct enables you to create object(s) of unnamed type as:
class //Nameless class!
{
//data members
}obj1, obj2;
In this example, obj1 and obj2 are declared to be objects of a class type which has not been given any name ā€” the class is nameless! In such situation, you cannot declare objects in a conventional sense (i.e Type obj1, obj2; sense). So this construct helps you do that.
You can even derive from other named classes while being nameless (and declaring the objects of the nameless class):
class : public A, public B //Nameless class is deriving from A and B
{
//data members
}obj1, obj2;
In short, this construct ensures that the user wouldn't be able to create more objects than intended, unless some evil programmer uses/misuses/abuses C++11 (or template) as:
decltype(obj1) obj3; //hehe!
Hope that helps!
It's shorthand for:
class C
{
....
};
C g_c;
You declare variables using the format type variable_name;. For example:
A x;
Where A may be the name of a class.
But instead of using a pre-existing class type, you can also define the class at the same time as you declare a variable of the new class's type:
class { ... } x;
or define the class and give it a name:
class A { ... } x;
In C++ it is common to just define the class and give it a name, but leave off the variable:
class A { ... };
but you don't have to leave off the variable.
That's just a way of creating objects of that type of Class. Structs mostly use them to initialize new variables.

cannot make outer class as member object inside inner class

I have 3 questions about below code:
class cb
{
public:
int y_;
class iterator
{
public:
//void func() { y_ = 5; } // (1)
private:
int x_;
//cb a; // (2)
};
void funcCB() { }
};
class Human
{
public:
void func() const {
cb c; // (3)
c.funcCB();
}
// (4)
};
1- Why i can't use Outer class's member variable y_ inside Inner class as in (1)?
2- Why i can't create object from Outer class inside inner class as in(2) but i can only create pointer and reference?
3- Why if i moved the line at (3) cb c; to line at (4) i get compile error ?
You can't use outer class field because it's not like your class iterator have direct access to it. First of all why would you want to have access to that field? I would think about redesign your solution first. But as you wish here is what you could do to solve the issue. You would need to have reference to the object which is your parent
class cb
{
public:
cb(): it(*this) {} // Passing the reference to ourself for iterator object init to have access in iterator class access to y_ field.
int y_;
class iterator
{
public:
iterator(cb& ob): a(ob) {}
void func() { a.y_ = 5; }
private:
int x_;
cb& a; // Reference to parent object
};
iterator it; // Added because I don't see the point where you don't want to have that object in your cb class.
void funcCB() { }
};
I'm not sure what would you like to achieve here. It will throw incomplete type because you will want to create cb object in which you will create iterator object in which you will create cb object in which again you will create iterator so you would get infinite recursion (if I understand that correctly). When you point iterator to concrete object it will stop the cycle.
You should change in class cb funcCB to be void funcCB() const {} because otherwise in class Human it is understanded that in func() which is const function you want to call funcCB() which will not modify the object c from Human class and there is a difference between qualifiers because you don't have const function in that case. You can also delete const qualifier in Human class for func and this will also work. Error here happens when you don't change qualifiers, because it is different when you have const function in which you create some object to further use and when you have object as a class field and you call function which cannot change the state of Human class and CB class don't have equivalent of const function for funcCB.
Why i can't use Outer class's member variable y_ inside Inner class as in (1)?
Because y_ is a non-static data member of class cb, meaning we must access it on a particular cb object. But here comes the problem. The assignment statement y_ = 5; is equivalent to:
vvvv--------------->this points to an object of type iterator and not cb
this->y_ = 5;
In the above shown equivalent statement, the this pointer points to the current instance of type iterator and not cb. But since to access y_ we must use a cb type object, we get the mentioned error.
Basically y_ should be accessed on an object of type cb. For example, you can make func to have a parameter of type cb& and then access y_ as shown below:
class cb
{
public:
int y_;
class iterator
{
public:
//------------vvv------------------->pass object of type cb by reference
void func(cb& it) { it.y_ = 5; } // (1) OK NOW
//----------------------^^---------->access member y_ on object it
private:
int x_;
};
void funcCB() { }
};
Why i can't create object from Outer class inside inner class as in(2) but i can only create pointer and reference?
Because at point #2 the class cb is incomplete and so at point #2 we cannot create a non-static data member of type cb. This can be seen from complete type documentation which states:
Any of the following contexts requires type T to be complete:
declaration of a non-static class data member of type T;
This means that at point #2 we cannot have a declaration for a non-static data member of type cb but we can still have a declaration for a non-static data member of type cb& or cb* as we can have a pointer or a reference to an incomplete type like cb.
Why if i moved the line at (3) cb c; to line at (4) i get compile error ?
If you moved line #3(cb c;) to line #4, you won't get any compile time error. Demo
class Human
{
public:
void func() const {
//cb c; // (3)
//c.funcCB();
}
cb c; // (4) perfectly fine
};
Forgive me if I don't quite get this -- my C++ is a little rusty.
Regarding question (1) -- Have you tried the "this" keyword?
E.g.,:
void func() { this->y_ = 5; }
Here is an example almost identical to yours:
'this' pointer in C++
For question 2, you're asking for a recursive inclusion of an object. That's like saying, What is an Onion? It is a Peel that contains an Onion. Well, that Onion inside is also a Peel that contains an Onion, then a Peel, then an Onion, etc. Without some mechanism to halt (an Onion might be a Core, which contains nothing), the first instantiation of the Onion object would loop infinitely until all memory was used up.
As a reference, the memory can be retrieved only when needed, and not before.
For question 3, I'm taking the lazy way out to say, them's just the rules.
UPDATE:
I'm not at work now, so I had more time to do a little more research. As I've said, my C++ is a little rusty.
Essentially for Q 1, what you're attempting to do is access the members of class "cb" from class "iterator". My research indicates that, just because "iterator" is a subclass of "cb", it doesn't get any special access privileges. So you can not access "cb::y_" from "iterator" and you can not use "this->y_" either. Methods (functions) inside the class can access "y_" directly. Sub-classes can not.
Note the following which compiles successfully:
class cb {
public:
int y_;
class iterator {
public:
void func() {
cb *z = new cb();
z->y_ = 5;
} // (1)
private:
int x_;
cb *a; // (2)
};
void funcCB() { }
};
class Human
{
public:
void func() const {
cb c; // (3)
c.funcCB();
}
// (4)
cb *z;
};
This probably is not what you're attempting to accomplish, but I expect that what you want to do can not be done the way you want. Your best bet would be to implement the "iterator" as its own class distinct from "cb" and make it a "friend" class of "cb". Or maybe better yet, and simpler, just include a set of iterator methods inside the class. The methods will have full access to all of the class attributes.
Also note the pointer reference to "cb". It does not compile as a straight object instantiation in a sub-class. Again, the Onion issue.
On a side note, remember that C++ is not Pascal. It's not Java. It can do sub-classes, but as you can see, it doesn't do them very well, or at least, it doesn't do them the way other languages do them. You're better off creating every class completely distinct from every other class, other than normal inheritance. That's sort of unofficially "The C++ Way."

C++ constructor and passing variables to another class

Well, just new in classes and trying to create a simple program, that has 2 classes. Class A and Class B. Well I'm trying to initialize my variable in constructor in class A, and then make some action and pass it to class B, where I'm also can make some action. So class A is a base class. However, when I compile the program I got two mistake -
error: ā€˜iā€™ was not declared in this scope
For class A and class B. So I have two question 1) why constructor doesn't declare variables (according to the books constructor called first)? 2) what ways I can transfer the variable from class A to use in class B?
#include <iostream>
#include <cstdio>
using namespace std;
class A {
public:
A(){
int i =1;
}
~A(){}
int foo () {
int p = i+1;
i++;
return p;
}
};
class B : public A {
public:
int showme() {
return i;
}
};
int main() {
A j;
B k;
cout<< k.showme()<<endl;
cout<< j.foo()<<endl;
return 0;
}
First off, get a good book:
The Definitive C++ Book Guide and List
and familiarize yourself with the basics. Your question indicates there is a complete mess right now in your understanding of C++.
Now on to the actual Q's.
1) C-tor does not declare a class member variable, it can only declare a local variable since a c-tor is also a function. You need to declare the member variable explicitly like so:
class A {
int i;
public:
A(int _i): i(_i) { }
};
2) The term "transfer" is incorrect per se. In this case, the two classes are in an inheritance hierarchy, so the variable i is inherited by class B and if you declare it as protected, then it will be accessible in the way you do it. The function B::showme() is defined correctly. Fix the first part and the example is going to work.
3) Do not confuse classes and objects. When there is an object of class A declared, it is in no way related to another object of class A or B. j and k share their own private instances of int i (provided that you fix (a)) and if you want to have k's instance of i to be equal to that of j, you can e.g. implement a copy constructor or a pair of getter/setter functions.

What does the name after the closing class bracket means?

I've encountered this code example and I remembered I've seen it before and I didn't know what it is for and what it does? I've searched on the internet but without luck.
Code:
class C
{
int x; // a non-static variable, implicitly private
public:
C() : x(0) {} // default constructor
// a static member function, which uses a non-static variable perfectly well
static int Incr(C& instance) { return ++(instance.x); }
} g_c;
int main(void)
{
C c2;
return C::Incr(g_c) + C::Incr(c2);
}
What does g_c after the last class bracket means?
} g_c;
Here g_c is declared to be an object of the class type C.
Such construct enables you to create object(s) of unnamed type as:
class //Nameless class!
{
//data members
}obj1, obj2;
In this example, obj1 and obj2 are declared to be objects of a class type which has not been given any name ā€” the class is nameless! In such situation, you cannot declare objects in a conventional sense (i.e Type obj1, obj2; sense). So this construct helps you do that.
You can even derive from other named classes while being nameless (and declaring the objects of the nameless class):
class : public A, public B //Nameless class is deriving from A and B
{
//data members
}obj1, obj2;
In short, this construct ensures that the user wouldn't be able to create more objects than intended, unless some evil programmer uses/misuses/abuses C++11 (or template) as:
decltype(obj1) obj3; //hehe!
Hope that helps!
It's shorthand for:
class C
{
....
};
C g_c;
You declare variables using the format type variable_name;. For example:
A x;
Where A may be the name of a class.
But instead of using a pre-existing class type, you can also define the class at the same time as you declare a variable of the new class's type:
class { ... } x;
or define the class and give it a name:
class A { ... } x;
In C++ it is common to just define the class and give it a name, but leave off the variable:
class A { ... };
but you don't have to leave off the variable.
That's just a way of creating objects of that type of Class. Structs mostly use them to initialize new variables.

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);
}