This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 9 years ago.
Consider the following class definition
class Pumpkin {
public:
Pumpkin(const Pumpkin & other);
~Pumpkin();
// more public member functions
private:
double radius;
// more private member variables
};
Which of the following functions must also be implemented for the Pumpkin class for it to function correctly?
(a) no parameter constructor
(b) operator=
(c) operator() (d) setRadius
(e) operator delete
Which of the following functions must also be implemented for the Pumpkin class for it to function correctly?
Well, of course the ones you declared in the class body. From what you have shown you'll definitely need to define both:
Pumpkin(const Pumpkin & other);
~Pumpkin();
and I don't see any particular reason to follow the Rule of Three, since you have only shown us an harmless double.
But, if you do any RAII or your copy constructor and/or destructor are non-trivial, that's probably the case. In which case you'll have to also define:
Pumpkin& operator=(const Pumpkin&);
and if you are using C++11, it's probably a good idea to define also:
Pumpkin(Pumpkin&&);
Pumpkin& operator=(Pumpkin&&);
namely called move-constructor and move-assignment respectively.
Related
This question already has answers here:
Object array initialization without default constructor
(14 answers)
Closed 2 years ago.
Let's say I have a class A :
class A{
public:
A(int const& someValue, std::string const& anotherOne);
private:
std::string m_string_member;
int m_int_member;
};
And I want to allocate an array of this class using new :
A* myClassArray = new A[69];
I get the error : No default constructor available.
Do I have to write a default constructor for every class I want to use by calling new ?
Short answer: Yes.
Long answer: Lets start with this matrix here https://foonathan.net/images/special-member-functions.png. You provide a constructor which is not the default constructor (yours takes arguments). So the compiler won't automagically generate a default constructor for you. However, in your allocation, you ask the compiler to default construct 69 elements. How should the compiler do this? But, solving this issue is rather easy. Just provide the default constructor, or, even easier, use = default. The latter only works because all your members are default-constructible.
In c++ if no user-declared constructors of any kind are provided for a class type the compiler will always declare a default constructor. If you provide any constructor and want default constructor as well, you should define default constructor explicitly.
This question already has answers here:
Why use functors over functions?
(7 answers)
Closed 3 years ago.
Why would you overload the () operator in a C++ class or struct in C++11 or higher? As far as I can tell, these operators are overloaded when you want to pass objects like classes or structs into a std::thread and kick off a new thread with a package of data to go along with it, through a callable type.
But other than that, why else would you overload the () operator? Couldn't you simply do the same things in the constructor for a class or struct?
Why use
struct MyCallableStruct{
void operator() () {
dosomething();
}
}
when you could do
struct MyCallableStruct{
MyCallableStruct() { dosomething(); }
}
They're totally different.
First and most importantly, When you use operator(), it can be passed as function parameters (by object).
In contrast, when implemented by constructor, it can only be passed through templates (by class)
Second, operator() can be called several times after object created,
while construtor can only be called at constructing
All in all, they're different and useful in different scenarios
This question already has answers here:
Two constructors, which is default?
(6 answers)
Closed 8 years ago.
Assuming that we have the class TestClass in our C++ project. A default constructor is the one empty parameters list. So we have:
TestClass();
TestClass(int defaultParam = 0);
Can these two be considered default constructors? And if they can be, is it ethical to have a default constructor like the second line?
Either of
TestClass(void);
TestClass(int defaultParam=0);
can be used as the default constructor. When you have both, it is a problem since the compiler cannot distinguish between the two when the compiler needs to use a default constructor. E.g.
TestClass anObject;
TestClass objectArray[5];
Unrelated to your question
For stylistic reasons, you should use:
TestClass();
instead of
TestClass(void);
The second form is supported by C++ but it's not necessary. The argument type void is necessary only when declaring functions in C.
having more than 1 constructor is called constructor overloading. If there are two default constructors it will generate an error as the compiler will not know which constructor to call while creating the object. If you don't declare a default constructor the complier does it by itself.
This question already has answers here:
When do we need to have a default constructor?
(7 answers)
Closed 8 years ago.
I have the following classes:
class ArithmeticExpression
{
public:
ArithmeticExpression(std::string expr);
}
class Command
{
public:
Command(){};
//this is a virtual class
}
class CommandAssign : public Command
{
private:
ArithmeticExpression expr;
public:
CommandAssign();
CommandAssign(ArithmeticExpression);
}
Now when I try to write the constructor for the CommandAssign class as in:
CommandAssign::CommandAssign(ArithmeticExpression expr)
:Command()
{
this -> expr = ArithmeticExpression(expr.getExpr());
}
I get the error:
no matching function for call to ‘ArithmeticExpression::ArithmeticExpression()’
:Command()
Apparently I can fix that by adding an empty constructor in ArithmeticExpression class that does not do anything. What is it so special about this empty constructor that makes it work? I do not explicitly call anywhere. Do you always need to define an empty constructor in C++?
I wanted to emphasize that although from the title it seems that my question is similar to the one some users suggested as being a duplicate of, the answer I was looking for is NOT there. I was simply trying to understand what happens when a constructor is called and how to avoid defining a useless default constructor, which I knew already is not automatically defined by the compiler in the case where I define one with parameters.
A default constructor will only be automatically generated by the compiler if no other constructors are defined.
EDIT:
The default constructor is needed for object initialization.
All members are initialised before the constructor body begins. If one doesn't have an entry in the initialiser list, then it will be default-initialised; but this is only possible (for a class type) if it has a default constructor.
expr is not initialised in the initialiser list, and doesn't have a default constructor (since declaring any constructor prevents one from being implicitly generated), so it can't be initialised - hence the error.
You should initialise it in the list, rather than reassigning it in the constructor body:
CommandAssign::CommandAssign(ArithmeticExpression expr) :
expr(expr.getExpr())
{}
Note that there's no need to explicitly default-construct the Command sub-object. This also requires the constructor of ArithmeticExpression to be public: it's private in your example code.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c++ call constructor from constructor
I have two constructors for the same class and I want one of the constructors to send data to the second constructor.
I know how to do it in C# but I'm new to C++ and I don't know if this is possible like so:
class a
{
public:
a (int x);
a (int x, int b, char g);
};
a :: a(int x) : this(x, 6, 'h')
{
}
New C++11 standard supports this feature (called delegating constructors). Syntax is like:
a::a(int x) : a(x, 6, 'h') {}
If your compiler doesn't support new standard, you will need to extract common behavior into another initialization method and call that method in the constructor body.
It's possible in C++11, but not in earlier versions.
Generally, you can try putting common stuff into a (non-virtual) member function, and call that from your constructors. While this won't allow you to init everything (only stuff that you do in the constructor bodies, not initialization in the preambles), it might still be "better than nothing".