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.
Related
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.
I have this large class that I want to separate into different classes. The reason why it was large because the class had many private variables and functions that are needed to run the program. I was tired of scrolling down the 1000+ lines of code trying to add or edit code. I am wondering if it is possible for the classes to interact with one base class that includes all the private/protected variables it needed to operate, or simply have them as global variables.
I am aware of inheritance as I tried having the separate classes be derived from the base class, by doing something similar to this:
#include <iostream>
class Base {
public:
void sayPrivateVar() {
std::cout << privateVar;
}
protected:
std::string privateVar = "I am a protected variable!";
};
class Derived : public Base {
public:
void manip() {
base->privateVar = "That was updated from a derived class";
}
private:
Base* base;
};
int main() {
Base base;
Derived derived;
derived.manip();
base.sayPrivateVar();
return 0;
}
EDIT: Without creating another object inside a class.
it depends on your class and what you have in it. It is often better not have inheritance because derived classes may then get member variables that they don't need. There are a few other ways you can do. One way would be to group you private variables in different classes and then have member variables in the first class.
E.g.
class X {
int x;
int y;
int angle;
...
};
becomes
class XYVector;
class X {
XYVector v;
};
class XYVector
{
int x;
int y;
int angle;
};
You can continue in this direction and instead of making them concrete class like XYVector above have them as interfaces : to have it more elaborate and flexible check out https://en.wikipedia.org/wiki/Composition_over_inheritance
At any rate: avoid having globally declared variables.
This is a good question and the answer is absolutely. Inheritance is actually a very good solution in this particular context since that is how object code shares it's scope with other classes. One important thing to note here is that how you call your derived class is important because the inherited scope is set along with the derived class (i.e. declaring it public base would inherit the public and protected methods as opposed to declaring it private which would give the derived class even more access!)
I have a class which has an attribute whose value depends on an attribute from its base class. This base class attribute is modified in the constructor so that I need its value after being modified. I tried to summarize the idea in this example:
#include <string>
#include <iostream>
class A
{
public:
int att_a;
A(int x) : att_a(x) {
att_a++;
}; // att_a is being modified in the constructor of A
};
class B : public A
{
public:
std::string att_b; // att_b is from a different type than att_a but its value is obtained from att_a
B(int y) : A(y), att_b(std::to_string(att_a)) {};
};
int main(int argc, char const *argv[])
{
B b = B(3);
std::cout << b.att_b << std::endl;
return 0;
}
I'm using attribute att_a from class A, which was modified during it's construction, as an input to a function that initializes att_b of class B. My concerns are:
Is that a good way of accomplishing what I want?
Even though it compiles and run, can it cause undefined behavior under certain circumstances?
Can it cause undefined behaviour?
No.
When using a member initialization list, the order is fully defined: First base-classes in their order, then members in their order. So at the time you create any member, all base classes and all previous declared members are instantiated. If you switch the order in your constructor, your compiler should output a warning.
Is it a good way of accomplishing what you want?
Since you don't tell us what you are going to do with those classes, i can't tell you if its a good way, but you can do it this way if it fits your needs.
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;
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.