calling constructor of a class member in constructor
Yes, certainly you can! That's what the constructor initializer list is for. This is an essential feature that you require to initialize members that don't have default constructors, as well as constants and references:
class Foo
{
Bar x; // requires Bar::Bar(char) constructor
const int n;
double & q;
public:
Foo(double & a, char b) : x(b), n(42), q(a) { }
// ^^^^^^^^^^^^^^^^^^^
};
You further need the initializer list to specify a non-default constructor for base classes in derived class constructors.
Calling a constructor of a member object within the body of the constructor?
The problem is that when C++ begins the execution of the constructor code all the member variables must have been already constructed (what if you for example call a method of Circle
before constructing it?).
If immediate construction is a problem then a possible solution is to add to your member a default constructor and the using assignment in the body of the constructor of the containing class.
You can imagine that native types like int
or double
do have a default constructor, that's why you can initialize them later (note however that for one of the many ugly quirks of the language the default constructor for an int
or a double
doesn't actually do anything in this case and you're not allowed to do anything with such a member except assigning it a value - for example reading it is not allowed).
You cannot use base(r)
in the body because that's not a valid statement... following a name with an opening parenthesis is only used for function call, for initialization in a declaration or for member initialization in the constructor member initialization list.
If you provide Circle
with a default constructor then you can do
Cylinder(double r, double h) {
base = Circle(r);
height = h;
}
Note however that the approach of constructing non-working objects to fix them later is not the best approach for C++. The language likes the idea that if an object is constructed then it's usable and deviations from this are considered only when necessary (C++11 drifted away a bit from this original path with move constructor... but that's another story).
How do I call one constructor from another in Java?
Yes, it is possible:
public class Foo {
private int x;
public Foo() {
this(1);
}
public Foo(int x) {
this.x = x;
}
}
To chain to a particular superclass constructor instead of one in the same class, use super
instead of this
. Note that you can only chain to one constructor, and it has to be the first statement in your constructor body.
See also this related question, which is about C# but where the same principles apply.
Calling Constructor with in constructor in same class
Inside this constructor:
A(int x, int y)
{
a = x;
b = y;
A(); // calling the default constructor
}
call A();
creates a new temporary object that is immediately deleted after this statement. Because the default constructor A()
does not initializes data members a
and b
then it outputs a garbage.
This temporary object has nothing common with the object created by constructor A( int, int )
.
You could rewrite your class the following way:
class A
{
public:
int a, b;
A(): A(0, 0) {}
A(int x, int y) : a(x), b(y)
{
cout << a << " " << b;
}
};
Calling constructor of class member when using malloc
malloc
is a C function, and has no knowledge of classes, constructors, etc.
If you are dead-set on using this, you are going to have to always call placement new
on each object (note: this requires including the header <new>
), and also manually calling the destructor before deallocating. You will also need to store the pointer that is returned from placement new
in order to avoid undefined behavior (as this is technically the only pointer that points to the start of the object's lifetime).
As you have in your edit, it will look something like:
auto cls = static_cast<MyClass*>(std::malloc(sizeof(MyClass)));
cls = new(cls) MyClass(/* any arguments here ... */);
cls->value = "hello";
cls->~MyClass();
std::free(cls);
However, be aware that by using malloc
you actually introduce other issues with respect to exception safety. If your placement-new
call throws an exception, the memory allocated by std::malloc
will leak -- which is bad. You also wouldn't want placement new
to operate on nullptr
if malloc
returns null, and would need to convey this error -- perhaps through an exception. You will probably want to wrap this into a helper that will ensure these conditions can't happen:
#include <new> // placement-new, std::bad_alloc
#include <utility> // std::forward
#include <cstdlib> // std::malloc, std::free
template <typename T, typename...Args>
T* make(Args&&...args)
{
auto* p = static_cast<T*>(std::malloc(sizeof(T)));
// Placement new can't operate on nullptr
if (p == nullptr) {
// alternatively, this could be 'return nullptr' if not using exceptions
throw std::bad_alloc{};
}
try {
p = new (p) T(std::forward<Args>(args)...);
} catch (...) {
std::free(p);
throw; // rethrow the exception here
}
return p;
};
Similarly, you will likely want to have a way to destroy objects while deallocating them, so that resources aren't leaked:
template <typename T>
void dispose(T* p)
{
p->~T();
std::free(p);
}
Using these utilities, the above example now becomes:
auto cls = make<MyClass>(/* any arguments here ... */);
cls->value = "hello";
dispose(cls);
If this seems like an awful lot of boilerplate, this is because this is exactly what new
and delete
already does for you. If you can, you will be much better off using these facilities when dealing with C++ types. This also allows you to continue using other RAII-wrappers like smart pointers easily without having to manually specify allocators (shared_ptr
) or deleters (unique_ptr
).
There really isn't a good reason IMO to prevent using new
and delete
in favor of malloc
/free
when working with C++ code. If you have a library that exposes a C-only interface but is implemented in C++ code -- it would actually be better for you to internalize the allocations and switch to new
and delete
rather than using malloc
and free
so you can save yourself the hassle.1
One other thing to be aware of is that if the types allocated in your system ever have a custom alignment via alignas
that exceeds alignof(std::max_align_t)
, using std::malloc
will be undefined behavior because it will be unable to satisfy the alignment requirements. This is another thing that new
/delete
would take care of for you.
1 If your "mixed C++/C" code is exposing a C interface at some point, it would be much cleaner for you to use new
and delete
rather than malloc
, and to simply expose the creation/deletion functions on your API explicitly. For example:
// C header:
extern "C"
my_class* make_my_class(void);
extern "C"
void dispose_my_class(my_class* p);
// C++ implementation:
extern "C"
my_class* make_my_class(void)
{
return new my_class{ ... };
}
extern "C"
void dispose_my_class(my_class* p)
{
delete p;
}
This is generally the approach taken for C/C++ interop.
Call constructor after declaration of a class variable
Members are created as soon as the object is created. As such, the constructor of Vector
has already been called on each of the three member vectors.
What you can do, assuming the vector is assignable, is construct a temporary vector, and assign it to a member:
eye = {a, b};
Can I call a constructor from another constructor (do constructor chaining) in C++?
C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:
You can combine two (or more) constructors via default parameters:
class Foo {
public:
Foo(char x, int y=0); // combines two constructors (char) and (char, int)
// ...
};Use an init method to share common code:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
// ...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
// ...
}
Foo::Foo(char x, int y)
{
init(x, y);
// ...
}
void Foo::init(char x, int y)
{
// ...
}
See the C++FAQ entry for reference.
When will C++ call the constructor on an object that is a class member?
Use the ctor-initializer. Members are initialized after base classes and before the constructor body runs.
MyClass::MyClass() : myObject(1,2,3) {
...
}
C++ Trying to pass Class to Constructor of Another Class
// declare the variable that I want to store Class1 in
Class1 stored_class;
You have a class member called stored_class1
. Now, let's take a look at your constructor:
Class2::Class2(Class1 storeClass1)
{
This constructor fails to initialize the stored_class
member. It does have a Class1
parameter. That's great, but just because a constructor has a parameter doesn't mean that the constructor will initialize a class member of the same type, automatically. You are responsible for doing this, yourself:
Class2::Class2(Class1 storeClass1)
: stored_class{storeClass1}
{
Related Topics
Static Global Variables in C++
Can Using a Lambda in Header Files Violate the Odr
How to Format Date Time Object with Format Dd/Mm/Yyyy
Operator << Must Take Exactly One Argument
How to Fix: /Usr/Lib/Libstdc++.So.6: Version 'Glibcxx_3.4.15' Not Found
Can You Allocate a Very Large Single Chunk of Memory ( > 4Gb ) in C or C++
How to Use Signal Inside a C++ Class
Should I Use Printf in My C++ Code
Pack Expansion for Alias Template
C++: Wrapping Vector<Char> with Istream
How to Use New Std::Byte Type in Places Where Old-Style Unsigned Char Is Needed
How to Use Qt Without Qmake or Qt Creator
Is There a C++11 Syntax File for Vim
How to Get Hash Code of a String in C++
Missing C++ Header <_Debug> After Updating Osx Command Line Tools 6.3
Opencv: How to Visualize a Depth Image
How to Perform Atomic Operations on Linux That Work on X86, Arm, Gcc and Icc