I want to call the constructor of a member m_foo of Class A in the constructor of Class A.
Is it nessecary to call it with m_foo = new Foo()? Or can I call it without putting it on the Heap?
I want to pass a pointer to an array of 256 Byte, so that the Foo object fills its member array with the data the pointer points to.
But how would I call a contructor of a member variable that I declare in the headerfile?
A.hpp
class A{
public
A();
private:
Foo m_foo;
};
A.cpp
A::A()
{
//How to call constructor of class Foo here?
}
Foo.hpp
class Foo()
{
Foo(char* p)
{
memcpy(m_Array, p, sizeof(m_Array)/sizeof(m_Array[0]));
}
private:
char m_Array[256];
};
Use the member initialization list for the A constructor :
A::A() : m_foo(...)
{
}
You can get the char* required to build m_foo from :
A constructor :
A::A(char* p) : m_foo(p) {}
Or another function :
A::A() : m_foo(GetBuffer()) {}
If you don't mind passing the pointer to A's constructor, this may be what you want:
class A
{
public:
A(const char* p);
private:
Foo m_foo;
};
A::A(const char* p) : m_foo(p) // <- calls Foo's ctor here
{
}
Related
I have something that looks like this:
class Foo
{
public:
Foo(parameter);
}
class Bar
{
Foo fooObject;
}
Bar::fooObject(data);
But I get:
error: expected constructor, destructor, or type conversion before '(' token
So my question is: how do I construct fooObject from outside Bar?
You can have a constructor that take an instance of Foo from outside of class and then you can copy or move that instance to your member variable. Another approach would be to take required parameters to construct an instance of Foo and then use member initializer list to construct member variable.
class Bar
{
public:
Bar(const Foo& foo) // Copy
: fooObject(foo)
{
}
Bar(Foo&& foo) // Move
: fooObject(std::move(foo))
{
}
Bar(int example)
: fooObject(example)
{
}
private:
Foo fooObject;
}
Initialize members using a constructor and member initializer list:
class Foo{
public:
Foo(int x);
};
class Bar{
public:
Bar(int param);
private:
Foo fooObject;
};
Bar::Bar(int param) : fooObject(param){};
If by outside of the class you mean the class member function definition then you would use the following syntax that goes into a source (.cpp) file:
Bar::Bar(int param) : fooObject(param){}; // ctor definition outside the class
The declarations can be placed in a header file.
I need to delay the constructor call, so I can initialize the value that should be passed to the constructor. I have written a short and very simplified example.
class A
{
private:
ObjectA* _ptr;
public:
A(ObjectA*);
};
class B
{
private:
A object; // The constructor seems to be called here?
ObjectA* obj;
public:
B();
};
A::A(ObjectA* ptr)
{
this->_ptr = ptr;
}
B::B()
{
obj = new ObjectA();
object(obj); // I want to call the 'A' constructor here, after initializing of 'obj'.
}
Is it possible?
No, you cannot defer a construction of a value member. You can use a pointer instead of a direct value but that's no solution for your problem.
The proper solution for your problem is using initialization list:
B::B ( ) : obj(new ObjectA), object(obj) {}
Also, you have to put obj before object in class B:
class B
{
private:
ObjectA *obj;
A object;
public:
B ( );
}
The reason for this is that, when a constructor is called, all of the objects members must be properly constructed and initialized. This is done using their default constructor.
The reason for reordering the class members is that the initializers of the members are called in the order they are declared in the class not in the order of their appearence in the initialization list.
Here is a solution I would use.
class B
{
private:
char m_aBytes[sizeof(A)];
A& getA () { return *(A*)m_aBytes; }
public:
B ()
{
ObjectA* objA = new ObjectA ();
new (m_aBytes) (objA);
}
}
Given the following classes:
class foo
{
private:
int c;
public:
foo( int a = 42 ) { c = a; }
~foo();
};
class bar: public foo
{
public:
bar();
~bar();
};
How can I make bar override c with a different number? Can I do something like this?
bar::bar()
{
c = 12;
}
I get this error when trying to compile:
test.cpp: In constructor ‘bar::bar()’:
test.cpp:8:7: error: ‘int foo::c’ is private
Call your base class' constructor in the constructor initialization list:
bar::bar()
: foo(12)
{ }
Incidentally, you should always prefer using a constructor initialization list over assignment inside the constructor body, so your foo constructor would be better written as:
foo( int a = 42 ) : c(a) { }
Call the base class constructor:
bar::bar() : foo(12) { }
Edit: whoops
You should use getter and setter methods for your private variables.
So your calls foo should look like this:
class foo
{
private:
int c;
public:
foo( int a = 42 ) { c = a; }
virtual ~foo();
void setC (int tempC){
c=tempC;
}
int getC() const{
return c;
}
};
In the constructor of B you can call them the setter method:
bar::bar()
{
setC(12);
}
You should then always use your setter and getter methods to access your variable, instead of accessing it direct.
You should also declare your destructor of your base class virtual.
What about
bar::bar() : foo(12) {}
I'm trying to set up a copy constructor and i'm getting this error
class Class1{
public:
int get_data();
void set_data(int);
private:
int d;
};
int Class1::get_data(){
return d;
}
void Class1::set_data(int data){
d = data;
}
class Class2 : public Class1{
Class2(const Class2&);
};
Class2::Class2(const Class2 &c2) : Class1(){
set_data(c2.set_data());
}
whats a solution to this problem. i read some of the previous questions and i understand why this is happening. but making set_data() const is not an option.
whats the accepted approach for copy constructors?
thanks,
You could just write a constructor for Class1 taking an int parameter:
class Class1 {
explicit Class1 (int i) : d (i) {}
// as before
};
class Class2 : public Class1 {
Class2 (Class2 const & c2) : Class1 (c2.get_data ()) {}
};
However, the default copy constructor should be enought here (i.e. you don't need to write your own, the compiler will do it for you).
Generally speaking, you should use initialisation lists:
http://www.parashift.com/c++-faq-lite/ctors.html
in the constructors (read the whole entry in the faq)
Edit: You forgot the 'const' qualifier for your get_data function.
Don't you want:
set_data(c2.get_data());
(and make the Class1::get_data() member function const)?
But you really should be using constructor initialization lists:
Class2::Class2(const Class2 &c2)
: Class1(c2)
{
}
This code uses the compiler-generated default copy constructor for Class1. In many cases you shouldn't use the default copy constructor or copy-assign operator overload, but here it's fine because the sole data member of Class1 is an int object.
In fact, you could even rely on the compiler-generated default copy constructor for Class2.
EDIT: Here is some example code:
#include <iostream>
class Class1{
public:
Class1() : d(0) { } // Provide a no-arg constructor to initialize `d`
int get_data() const; // Class1::get_data() is `const` because it does not change the `Class1` object.
void set_data(int);
private:
int d;
};
int Class1::get_data() const{
return d;
}
void Class1::set_data(int data){
d = data;
}
class Class2 : public Class1{
public:
Class2();
};
Class2::Class2()
: Class1()
{
}
int main() {
Class2 other_c2;
other_c2.set_data(14);
Class2 c2(other_c2);
std::cout << c2.get_data() << '\n';
}
http://codepad.org/jlplTYrH
let's say I have a class
class MyClass {
public:
AnotherClass myObject;
};
My issue is that I want to initialize myObject with arguments to it's constructor, exactly if I were declaring it on the stack during a function
AnotherClass myObject(1, 2, 3);
but I want to do this for the class member in the constructor:
MyClass::MyClass() {
myObject = ...?
...
}
The problem is exactly that. If I declare a class member that has a constructor, will C++ call the default constructor? How can I still declare the variable in the class definition but initialize it in the constructor?
Thanks for any answers!
Use the ctor-initializer. Members are initialized after base classes and before the constructor body runs.
MyClass::MyClass() : myObject(1,2,3) {
...
}
You can use an initializer list.
class MyClass {
public:
MyClass() : myObject(1,2,3){ }
AnotherClass myObject;
};
Google for Constructor initialization lists
http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/
class A
{
public:
A(int);
};
class B
{
public:
B();
private:
A my_a_;
};
// initialize my_a by passing zero to its constructor
B::B() : my_a_(0)
{
}
always use the initializer list:
MyClass::MyClass() :
myObject( 1, 2, 3 )
{
//myObject = don't do this, bad practice!
}
see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6
The best method I can think of is to initialize the member in the class ctor, like so:
class MyClass
{
public:
MyClass(int param)
: m_Object(param)
{ };
private:
OtherClass m_Object;
};
You can then explicitly initialize the member with whichever ctor you want (as well as providing multiple ctors with different params for both classes).
Or provide proper constructors:
struct Foo{
Foo(const Bar& b): myBar(b){}
Bar myBar;
}
//...
Foo myFoo1( Bar(1,2,3) );
Foo myFoo2( Bar(3,2,1) );
Or if you don't want to expose bar then you can set parameters, for example
struct Square{
Square(const int height, const int width): myDimension(width,height){}
Dimension myDimension;
}
//...
Square sq(1,2);
Square sq(4,3);