I have a class made up of several fields, and I have several constructors. I also have a constructor that doesn't take any parameters, but when I try to use it:
int main {
A a;
}
The compiler generates an error, while if I use it like this:
int main {
A a();
}
It's ok. What's that?
Thank you
The first main uses A's default constructor. The second one declares a function that takes no parameters and returns an A by value, which probably isn't what you intend.
So what does the definition of A look like and what is the error that the compiler generates?
Oh, and you need to provide a parameter list in the declaration of main: int main() { //... , not int main { //...
By OK you mean it compiles or that it works? The line of code:
A a();
is a declaration (or prototype) of a function named a that takes no parameters and returns an object of type A.
I think for anyone to have a chance to help you with your real problem you'll need to post at least the declaration for class A.
Charles and Michael Burr both identified that the second declaration was in fact a function prototype and not an instantiation of A.
As for possible reasons why your first code snippet did not work, you would get a compilation error in this situation when:
Class A inherits from a base class that has no default constructor; OR
Class A contains objects of types that have no default constructor; OR
Class A contains reference members;
AND
You have provided a default constructor which omits one or more of these subobjects from its initialiser list.
All of these subobjects need some way to be initialised, and the default constructor produced by the compiler won't do it. Note that in all cases you need to initialise them in the initialiser list, not the body of the constructor.
You're both right, I had a problem inside the class.
Related
I have confusion after reading from some places.
I'm doing example from this page
let's say there's a class(Book) which has an object(Author) as one of its member. Here's the constructor:
Book::Book(string name, Author author, double price, int qtyInStock)
: name(name), author(author) { **// Must use member initializer list to construct object**
// Call setters to validate price and qtyInStock
setPrice(price);
setQtyInStock(qtyInStock);
}
I tried to declare the object author inside the constructor instead of initializer lisr. It gave me error. no matching function to call Author::Author() --> which is the default constuctor of Author.
After reading from these stackoverflow posts : this1 and this2
What I understand is that, summarizing from those 2:
an object is considered & must be fully initialised when execution enters the body of the constructor
An object has all of its members initialised in the initialisation list. Even if you do not explicitly initialise them there, the compiler will happily do so for you
native types like int or double do have a default constructor
So from all of those above, what I understand is a user defined object/class DOES NOT automatically have DEFAULT CONSTRUCTOR, unlike the primitive types.
That's why it gives error, if I do not use member initializer list (which calls copy constructor) , cause the compiler tries to initialize it using default consturctor which it(user defined class) does not have.
And so possible solutions are: define a default constructor for the class, or use member initializer
AND THEN I read this post on stackoverflow saying that:
"How Many default methods does a class have?" and the answer mentions that It HAS DEFAULT CONSTRUCTOR
1. If it has default consturctor, Why does my first case( the book and author classes) give error?
Also I read from this page, lets say I defined a class Point before, then page wrote:
Point p1; // **Invoke default constructor**
// OR Point p1 = Point(); NOT Point p1();
2. So when we declare like above, does it INVOKE DEFAULT CONSTRUCTOR? Why it does not give an error if so? I thought a class does not have a default constructor?
Appreciate if you can help me to clarify things here, and answer the two questons above (italic)
The full answer is big, and is presented here:
http://en.cppreference.com/w/cpp/language/default_constructor
If you specifically make one, there is always a default constructor. This includes constructors that MAY accept parameters but don't have to - constructors with default parameters and variadic templates can both be default constructors.
If you mark it as = delete then it will never have one.
Otherwise, if no user-provided constructors are present the compiler will try to make one for you except for in certain circumstances (fully listed in the link above in the Deleted implicitly-declared default constructor section)
T has a member of reference type without a default initializer.
T has a const member without user-defined default constructor or a default member initializer (since C++11).
T has a member (without a default member initializer) (since C++11) which has a deleted default constructor, or its default constructor is ambiguous or inaccessible from this constructor.
T has a direct or virtual base which has a deleted default constructor, or it is ambiguous or inaccessible from this constructor.
T has a direct or virtual base which has a deleted destructor, or a destructor that is inaccessible from this constructor.
T is a non-union class with a variant member M with a non-trivial default constructor, and no variant member of the anonymous union containing M has a default member initializer.
and some additional rules for union types.
tl;dr: it's complicated.
Implicit default constructors are not created for all objects.
The main rule is that when an object has no constructors of any kind, it gets assign an implicit default constructor.
I won't go over all the specific rules dictating when they get created, you're better off reading them from here.
As for your question 1 on the error message:
I tried to declare the object author inside the constructor instead of initializer list. It gave me error.
You don't show the code that produced the error, so I will assume it is like below - correct me if I'm wrong.
// sample A - Bad code, wont compile
class Author { };
class Book
{
public:
Book(int x, Author y): n(1) {
a(y); //-this line does NOT compile.
// initialization of a must be in the initializer list,
// between : and {
}
private:
Author a;
int n;
};
The reason the above does not compile is because it is a language rule that nested objects declared by value must be initialized in one of these 2 ways:
- within the initializer list
- implicitly, by letting the compiler call the default constructor - which will work if the object has one.
Finally, on your question 2, yes, that sample declaration of Point does invoke the default constructor, if the class has one. Again, refer to language reference to clarify on when the default constructor exists or not.
This is really question on C++ language, what does SNeuron(int NumInputs); mean inside the structure? I'm not c++ programer and this construction inside structure looks strange to me. Can anybody explain it what it could be for? I already tried google.
struct SNeuron
{
//the number of inputs into the neuron
int m_NumInputs;
//the weights for each input
vector<double> m_vecWeight;
//ctor
SNeuron(int NumInputs);
};
A struct in C++ is exactly the same as a class, except that all members of a struct are public by default.
So what you are seeing here is simply a constructor declaration for the struct.
The reason, I believe, is to make interoperability with C easier.
It's simply declaring a constructor for the struct SNeuron. This is called a prototype method, and won't wok unless it's implemented later on. It could be implemented inside the class by saying
SNeuron(int NumInputs) {
// Constructor code
}
or outside like this:
SNeuron::SNeuron(int NumInputs) {
// Constructor code
}
The main use of this would be to initialize the fields m_NumInputs and m_vecWeight.
When an instance of the structure is created, it need to be "constructed" (i.e. initialized), that is done by having constructor functions, which are automatically called by the compiler when an instance is created.
For example, in the following declaration and definition of a variable using the structure, the constructor will be called:
SNeuron myNeuron(5); // Creates the instance and calls the constructor function
That is simply a constructor. A constructor is basically a mechanism by which you initialize all the data members of a class when an object of that class type is created.
You can write constructors for both struct and class.
But that constructor which you declared in your code is not the default constructor because a default constructor is that constructor which takes no arguments.
I have a class with its constructor having a parameter. Now I had to declare class A object. But I need to call the constructor later. But if I do that, I get the error.
e.g.
class A{
public:
int a;
A(int x){
a=x;
}
};
int main(){
A a;
a=A(3);
}
Error
temp.cpp: In function ‘int main()’:
temp.cpp:10:4: error: no matching function for call to ‘A::A()’
temp.cpp:10:4: note: candidates are:
temp.cpp:5:2: note: A::A(int)
temp.cpp:5:2: note: candidate expects 1 argument, 0 provided
temp.cpp:3:7: note: A::A(const A&)
temp.cpp:3:7: note: candidate expects 1 argument, 0 provided
The only good solution here is to avoid this situation arising in the first place.
The situation typically arises when you have something on the general order of having to create an object where its initial value depends on some condition, so conceptually what you want is something on this general order:
if (xyz)
A a(123);
else
A a(456);
// code that uses A goes here
The problem in this case is that in this case, A goes out of scope before you can use it. The cure is typically to divide this code up into two functions, so you end up with something like this:
if (xyz)
code_that_uses_A(123);
else
code_that_uses_A(456);
Although I certainly prefer to avoid it, there is another possibility that can be workable: a wrapper object that keeps track of whether the object it contains has been initialized or not. For example, it can contain a pointer to the actual object. This is initialized to a null pointer. When you initialize the object it contains, you allocate a contained object. Depending on what you want, attempting to re-initialize the container object could throw or it could just assign a new value to the contained object.
Of these two, the former is nearly always preferable. It tends to clean up the code and give each individual piece of code a single, clear responsibility. The latter can work, but generally requires quite a bit of work to get the wrapper object present a clean interface. Although I'd usually consider it a lesser concern, such a wrapper typically adds substantial overhead to using the wrapped object.
The very point of the constructor with parameter is to ensure that no object of the class may exist without a initialised. You cannot "call constructor later". You may add another constructor though, without parameters.
Whenever you define an object. constructors get automatically called. What you may have as below:
class A{
int a;
public:
A(int x = 0){
a=x;
}
A(const A&arg) {a = arg.a;}
A& operator =(const A&arg) {a = arg.a;return *this;}
};
int main(){
A a;
a=A(3);
return 0;
}
Constructors may also have default arguments, so A a; might actually be implemented as like a call to constructor A(0) See Default parameters with C++ constructors
The issue here is that you have defined a constructor for A class which takes int as an argument.
As you have defined your own constructor, compiler will not define default constructor for your class.
A(int x)
{
a=x;
}
When you call:
A a;
This will look for a constructor for A class which does not take any argument. But that is not present. Thus the compilation error is coming.
You should initialize any instance of a class. There is no way to have a "dummy" variable in no well-defined state, unless your class has a constructor without arguments.
Or, add a constructor with no arguments.
Note that assignment in a = A(3) calls an assignment operator on a.
I have two classes, one has permitted making the only explicitly declared constructor, the no arguments one, private. I recently added another class but am getting compile-time errors due to having made the no argument constructor private. The only difference is the first had a public static factory method while the latter has a non-static constructor which takes an argument.
Thanks, hope this makes some sense.
Okay, I give you some code:
This doesn't compile:
class GridElem {
public:
GridElem(const char _idata);
~GridElem();
private:
GridElem();
}
This does compile:
class GridElem {
public:
GridElem(const char _idata);
~GridElem();
GridElem();
}
This does compile:
class MyClass {
public:
~MyClass();
private:
MyClass();
Not a complete example, sorry, but I believe this shows where the anomally arises, perhaps from extending cocos2d::Layer?
EDIT
Alright I found the call that is doing this (eclipse couldn't find it :()
in header
GridElem myGrid[15][15];
in cpp file
MyClass::MyClass() : myGrid{0} {}
I only recently changed it from a smaller grid and giving each element explicitly (because it was still just 0 for want of more information), I think this must now expand to parameterless c'tor. I completely forgot that, sorry, but it wasn't 100% obvious mistake.
You can always make the default constructor private (or not have a default constructor at all).
What you can't do is use a private default constructor from outside the class (or its friends).
You haven't provided enough context to know for sure, but I suspect your problem is that something else in your code is trying to default construct a GridElem, so it needs to be public.
The only difference is the first had a public static factory method while the latter has a non-static constructor which takes an argument.
If MyScene has a factory method then that's a member and can call the private default constructor. There's no "anomaly", you've just said that both types can only be default constructed by their own member functions (and friends), but only one of them has a member function to actually do that.
making default constructor private usually means you want all
creation to go through a factory. So use said factory, or make it public
I am writing the following classes in C++.
class SImage {
...
public:
SImage(char*);
}
class SImageProc {
SImage S;
...
public:
SImageProc(SImage Im) { S = Im; };
}
When compiling I receive this referencing the line where I implement my constructor:
SImageProc.cpp:5:33: error: no matching function for call to 'SImage::SImage()'
I cannot figure out why it is interpreting my parameters as instantions of a class when implementing the SImageProc class.
SImage does not have a default constructor, because you have provided constructor SImage(char*). This means the compiler no longer provides a default one. Something elsewhere in your code requires SImage, causing the error.
You need to provide a default constructor for SImage, or remove the code that requires it. It is not possible to say which one of the solutions is suitable without more details.
My wild guess would be that SImageProc has an SImage data member, and you are not initializing it in the constructor initialization list. This is how you would fix that problem:
SImageProc(SImage Im) : S(Im) {};
The explanation for that is that, by the time you reach a constructor's body, all data members and bases have been initialized. After initialization you can only modify them (in your example, you were assigning to S.) If you do not explicitly initialize data members and bases in the constructor initialization list, they (usually) get default initialized, which in the case of a user defined type means the default constructor is called. This is the source of the error.