This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
I'm pretty new to c++, i'm now trying to learn all the basics,
I know when default constructors are called, but when i tried different syntax it doesn't work like i expected.
Look at the following code:
class a;
class b();
class c(NULL);
'class' is a class i created with default constructor,
for a and c everything works well, but for b it just won't recognize the variable as a class member.
As i see it b and c are basically the same, what's wrong than?
Thanks!
Don't name your class "class", as it is a reserved name.
As for C++, if the constructor takes no parameters, you instantiate it using
Foo a; // note, if you are using c++11, you can do Foo a{};
As opposed to:
Foo b();
Which actually does something totally unexpected*, and declares a function named b that returns a Foo instance.
As for Foo c(null), it won't compile as there is no default constructor that takes an argument.
* It is referred to as "the most vexing parse", though I find that to be an exaggeration. It can certainly catch you by surprise, but just knowing that you can declare a function prototype inside a function, should be enough to remove the "vexing" aspect.
In other words int getMyInt(); is obviously a function prototype when placed outside any function definitions. However, since this is also the case when inside a function definition, int getMyInt(); doesn't do anything it wouldn't normally do... which is to define a function prototype getMyInt that returns an integer.
b is interpreted as a declaration of a function taking no arguments and returning an object of type class.
This is known as the most vexing parse. Edit: This is not the most vexing parse.
Related
This question already has an answer here:
Most vexing parse
(1 answer)
Closed 2 years ago.
Here C() is a temporary object which should have been created with no-arg constructor and then I expected a call to move constructor. Yet none of them happened. Can someone exmplain why?
#include <iostream>
using namespace std;
class C{
public:
C(){std::cout<<"No arg\n";}
C(const C& r){std:cout<<"Copy Cons\n";}
C(C&& r){std:cout<<"Move Cons\n";}
};
int main() {
C c(C());
}
The statement C c(C()); is actually a function declaration for a function called c that returns C and takes a function (unnamed) as a parameter that returns a C and takes no parameters.
In other words, it's purely declarative and has no effect on the program.
This is an example of the most vexing parse.
Even if it we fixed that (with C c((C())) or C c{C()}) , pre-C++17 most compilers used permission granted by the language to optimise away that "extra" temporary object (and since C++17 they must do so), so at best you'd probably only see the output from a single default constructor invocation.
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 5 years ago.
Suppose I have the following structure:
struct A {
A() { cout << "Default ctor\n"; }
A(int) { cout << "Ctor with params\n"; }
};
And then I want to create an object. In Java I've got accustomed to use brackets when I create an object, so the first desire is to write something like that:
A a();
The code compiles, but a actually isn't an instance of A, it is something different.
So the question is: what is a and why should I omit the brackets to call the default constructor?
See the most vexing parse, what you are actually doing is declaring a function. The way to alleviate this problem is to either eliminate the () or to use the C++11 uniform initialization syntax,
A a;
A a{};
In C++, A a(); is a forward declaration for a function called a that takes no arguments, and returns an A. It does not create an instance of A using the default constructor.
In Java, there is no need for forward declarations of functions, so A a(); can be read to be equivalent to A a;
This curiousity of C++ even has a name: see https://en.wikipedia.org/wiki/Most_vexing_parse
This question already has answers here:
what is 'class' in 'class DataType* Variable' in Unreal Engine Shooter Game Sample
(3 answers)
Closed 7 years ago.
I came across a piece of code that looked like this:
class SomeClass* GetSomeClass()
{
return _instanceOfSomeClass;
}
What does the "class" keyword do on the return type? I can't find anywhere that explains what it's function is. Does it just specify that it's talking about SomeClass as a class in case there is some sort of ambiguousness or something? I am confused.
class SomeClass is a longhand way of referring to the class type SomeClass (technically, it's the elaborated type specifier). Usually, adding class is redundant, and the two are equivalent. But it's sometimes necessary to resolve the ambiguity, if there's a variable or function with the same name.
It is used to disambiguate.
Say for example if you have a variable of the same name in the same (or outer) scope, something like this:
int SomeClass; //SomeClass is declared to be variable here
class SomeClass* GetSomeClass()
{
return _instanceOfSomeClass;
}
Without the class keyword, the function declaration wouldn't make sense to the compiler. The class keyword tells the compiler to ignore the variable declaration, and look for a class declaration.
It's a forward declaration. It allows you to just say "there is a class SomeClass somewhere in my program, it is just not visible to this file in order to prevent redeclerations".
Whenever you implement this function, though, the file must have actual interface of class SomeClass.
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 10 years ago.
I cannot do this:
class A
{
public:
A()
{
}
};
A a1();
Because A a1(); looks like a function prototype.
But I can do this:
class B
{
public:
B(std::string argument)
{
std::cout << argument;
}
};
B b1("Text");
These two things are essentially the same except the compiler is able to distinguish B b1("Text"); as NOT being a function prototype, because some data is passed in the parenthesis.
Is there any reason why the brackets must be omitted for A, or is the reason because the compiler thinks it is a function definition?
That's exactly it, and it's known as most vexing parse. The reason is that if A a1(); was treated as an object declaration, you wouldn't be able to declare a function with that prototype. And you want to be able to declare a function, right?
B b1("Text"); works because it can't be treated as a function prototype, but, for example, B b(A()); can and will.
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
Consider the following code.
Here, A a(B()) compiles even though the constructor is A(B& b);
But print(B()) does not work. But print is also declared as print(B& b);
Why this inconsistency?
#include <iostream>
using namespace std;
class B{
public:
char b;
};
class A {
public:
B b;
A(B& b);
A() { }
};
A::A(B& b) {
this->b = b;
}
void print(B& b) { }
int main(){
print(B());
A a(B());
}
It compiles because it's not creating an instance of A. It's declaring a function named a that returns an A and receives one unnamed parameter of type pointer-to-function-returning-B. Since it's just a declaration, it compiles. If you're referred to a elsewhere in the code, you'd have seen additional problems. For why that's a function declaration instead of an object definition, the term to look up is most vexing parse.
This:
A a(B());
isn't doing what you think. It is actually parsed as a function declaration. This is commonly referred to as the "most vexing parse" in C++ (there are many posts here about it, if you search for that phrase).
You should not be passing a non-constant reference to a temporary, so the print statement should not compile. If you modify that reference in print to const, it will work.
Where you are trying to call the constructor you are actually declaring a function:
A a(B());
This declares a as a function returning A and taking as parameter a function pointer returning B and taking no parameters.
Actually trying to call the constructor results in an error, as expected:
A a = A(B());
tst.cpp:32: error: no matching function for call to ‘A::A(B)’