I want to write a C++ program in which an object of a parameterized class A-'a' has to be initialized inside another class B. I should not/can not initialize like 'A a(parameter list);' of class A while declaring the object variable 'a' which is outside the constructor of class B. The necessary parameters to the object 'a' are gotten through the constructor of B. How to initialize 'a' inside B's constructor with the required parameters?
Class A{
public:
A(string s)
{cout<<s;}
};
class B{
private:
A a;
public:
B(string path){
a(path);
}
};
With the above code I am getting errors. How to initialize the object a(path) inside the class B?
The feature you are looking for is member initializer list. In your example it would be used like this:
class B{
B(string path) : a(path) {
}
};
Related
So I have class A, which has an object of class B as a class variable.
I constructed an object of class B in the main (objB) , and use class A's constructor to pass objB into class A (and assigned it to class variable called objC of type B).
How can I make it so whenever I call objC.do() it can change the original objB as well?
Instead of having a B member, use a reference as a member:
class A {
B& the_b;
// etc.
public:
A(B& some_b) : the_B { some_B } { }
}
If I have 2 classes, one with a custom constructor, and the other with an instance of the first class. How do I create that instance with the custom constructor.
For example:
a.h
class A
{
public:
A(std::string input);
};
b.h
Class B
{
public:
A a("Greetings");
};
This wouldn't work properly, it gives the error "expected a type specifier" on the string itself, and whenever I use a member of class A in class B, it says "expression must have a class type"
I'm assuming this means I'd need to make it
A a(std::string words);
But I'm not sure where or how I would define what the string should be.
Use the constructor's initialization list:
class A
{
public:
A (std::string input);
};
class B
{
A a;
public:
B (std::string s) : a (s) {}; //This calls the constructor of A on 'a'
};
Also, in C++11 you can use the uniform initializer syntax:
class B
{
A a {"Greetings"}.
...
};
But with this, you can only call the constructor with a compile-time constant.
I think the question title may be impossible to get right but, I have a class (lets call it A) which has a constructor that needs a pointer to another class (called B). This would be fine but when I define a class in a third class (called C), then I get this error after putting a variable into the constructor: error: expected identifier before ‘&’ token, then if I remove the & I get: error: ‘ClassA’ is not a type.
For those who can't understand what I just said (I don't blame you), here is an example:
class A
{
private:
int number;
//etc, etc...
};
class B
{
private:
A* ClassAPntr;
public:
B(A* objectPointer)
{
ClassAPntr = objectPointer;
}
};
class C
{
private:
A ClassA;
B ClassB(&ClassA);
};
int main()
{
C classC;
}
You didn't actually declare a constructor for class C. What you meant to do was this:
class C
{
public:
C()
: b(&a) // you have to provide the arguments to B's constructor here
{ }
private:
A a;
B b; // ... not here
};
Just for clarification, when you did composition by adding A classA private object to class C, the compiler accept this step because A has undefined constructor which means the compiler will make a default constructor for you and call it when make A classA.
The problem in class B because it has a non-default user defined constructor which means that compiler should force you to call it in class C through constructor initialization list or through curly braces in c++11, so it becomes your responsibility simply because compiler can't know which address for which class A Object you are going to pass for class B
constructor.
So why did you get this error message : class A is not a type or expected identifier before ‘&’ token?
the answer is that compiler considered B ClassB(&ClassA) a declaration for a private function with name ClassB and a return value of type B class.
and because you never use this function in your class the compiler will never give you any error related to definition. and you will also never use this member function in other functions like main because it is private
to produce the undefined reference error you can modify c class to be like this:
class C
{
private:
A classA;
B classB();
friend B func() ;
};
B func() {
C c;
return c.classB(); // undefined reference Error
}
such is the code,and with the error:"illegal member initialization: 'a' is not a base or member",what is the meaning of the error info,and why??
class A{
public:
int a;
};
class B:public A{
public:
B();
};
B::B():a(10){ // put "a(10)" into the constructor body is right
}
By the time the constructor of the derived class is invoked, the base class must already be constructed. So it's already too late. To see why it must be this way, consider:
class Base
{
public:
int i;
Base(int q) : i(q) { ; }
};
class Middle : public Base
{
public:
Middle() : Base(2) { printf("i=%d\n", i); }
};
class Derived : public Middle
{
public:
Derived() : i(3) { ; }
}
Now, think about it. The Middle constructor has to run before the Derived constructor. And the Middle constructor ensures that i is 2. So how can the Derived constructor later re-construct it with a different value?
See this answer for a more complete explanation of what's going on here. Basically, you cannot initialise A::a in the initialiser of B, because it is ill-formed according to the standard.
One more important piece of information - remember that if a class does not initialise a member object via the constructor initialization list, then the default constructor for that member will be invoked before that first statement in the base class constructor is executed. When you use the initialiser, what you are actually doing is specifying a constructor to be used INSTEAD of the default constructor.
Clearly when you are constructing a derived class, the parent class member has thus already been constructed, so you cannot reconstruct the base member again, which is what you are trying to do in this example by including it in the derived class initialisation list.
As an aside, if you all you want is to have the derived class be able to set the value of A::a to a specific value, then use the following code instead:
B::B()
{
a = 10;
}
Because the base class may want to initialize things its own way. The proper method is to call on of the base constructors in the initializer list and let the base ctor initialize itself.
Newbie here. I am looking at company code.
It appears that there are NO member variables in class A yet in A's constructor it initializes an object B even though class A does not contain any member variable of type B (or any member variable at all!).
I guess I don't understand it enough to even ask a question...so what's going on here!? My intuition is that you need a variable before you even try to initialize it. How is it possible (or what good does it do) to initialize an object without having the object?
.h:
class A: public B
{
public:
A(bool r = true);
virtual ~A;
private:
}
.cpp:
A::A(bool r) : B(r ? B::someEnumeration : B::anotherEnumeration)
{
}
A::~A()
{
}
Please help.
Thanks,
jbu
Class A (publicly) inherits from class B:
class A: public B
The only way to initialize a base class with parameters is through the initializer list.
This is actually the only way to call the ctor of a base class in C++ as there is noch such thing as super().
class A : public B
{
};
class B
{
public:
int x;
};
A is a derived type from B. Or A inherits B.
So this is valid...
A a;
a.x = 3;
The rest of your code is just calling B's constructor when A is constructed.
class A: public B
{
public:
A(bool r = true); // defaults parameter 1 as "true" if no arguments provided ex A *pA = new A();
virtual ~A;
private:
}
.cpp
A::A(bool r) : B(r ? B::someEnumeration : B::anotherEnumeration)
{
// calls parent class, and initialize argument 1 with some enumeration based on whether r is true or false
}
A::~A()
{
}
Since construtor cannot be inherited so base class data members are to be initialized by passying argument in derived class constructor and with the help of initialization list.
You should also know that in case of polymorphic class initialization of vptr to respective virtual table is done only in constructor.