This question already has answers here:
"Incomplete type" in class which has a member of the same type of the class itself
(8 answers)
Closed 6 years ago.
I've been working with a lot of C and Java lately so I'm a bit confused coming back to C++ on why this is not allowed.
incomplete type is not allowed
#pragma once
class Expression
{
private:
Expression power; // <--- incomplete type is not allowed
};
I believe the answer here is to change the line Expression power to Expression *power but I don't understand why that is. I can declare objects like vector<int> var without having to make them a pointer, but the second I have an object of the same type as the file it's being declared in, I need one? I've looked around but cannot find any tutorials/videos on a class making an object of itself.
If you put an instance of a class inside itself, if you notice, you are creating recursion, since every instance has its own Expression power, and this goes on forever. If you have a pointer though, you can control this infinite recursion, since at any time you can set power to nullptr, (or NULL/0, pre C++11), to end the recursion.
Related
This question already has answers here:
how does the ampersand(&) sign work in c++? [duplicate]
(3 answers)
What does '&' do in a C++ declaration?
(7 answers)
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 2 years ago.
I am a novice trying to understand some C++ code in the open-source game Simutrans. Specifically, this declaration (line 79 in this header file):
class env_t
{
public:
<snip>
/// if we are the server, we are at this port
/// #see network_init_server()
static const uint16 &server;
The context tells us this line concerns public data members of the class env_t. The static keyword tells us that all objects of class env_t will have the property server.
Server's type is uint16 (a 16-bit unsigned integer) and it is a constant (so it cannot be overwritten in normal circumstances).
The part that puzzles me is why there is an ampersand (&) at the beginning of the member's name. I have only previously come across the ampersand in bitwise arithmetic and as the "address of" operator. Neither of those uses fit here: there is no arithmetic and I do not see how you could define server as the address of server. Wouldn't that be telling the program that the only possible value of the variable is the variable's own memory address? That not only seems to be circular, but it seems to be inconsistent with the fact that the program can definitely use more than 16 bits of memory addresses for other purposes.
It has been difficult to search for explanations because the ampersand is also a search operator. But this article gives seven different uses of ampersands in C++ and none of them seem to fit here. It's not an expression nor a double ampersand. According to these S.O. answers, the ampersand can be used in a function template to indicate that a parameter must be of a reference type. But my example is declaring a data member, which is not a template, and indeed not any kind of function. And the type is clearly uint16, right? So what does the ampersand indicate here, please?
It should be noted that Simutrans is more than two decades old, before all platforms had the Standard Library, so its code is sometimes idiosyncratic. But I am sure the more relevant fact is that I'm a beginner at C++!
That notation indicates that server is a reference. This has enough similarities to pointers that if you are comfortable with them, you can think of them as a very restricted pointer. If you aren't so comfortable with pointers, a reference is not a variable that holds onto its own data. Rather, it is a reference to another variable. This notation indicates that server is actually referring to data somewhere else, most likely outside of your env_t class.
This is typically done for two reasons. One is that if you change this value, it changes the value of the actual variable being referred to, so that if another piece of code looks at its value, they'll see your change. Vice versa, if someone else changes the value of the variable referenced by server, and you query the value of server, you'll see their changes.
This question already has answers here:
C++ auto keyword. Why is it magic?
(8 answers)
Closed 3 years ago.
I came across a curious line of code of the form:
// Given the following definitions:
class B;
B b;
// Line of interest:
auto a(b);
I thought it must be a typo, but after some experimentation found out that it works, and seems to always call the copy constructor of the type of b (even if you have other classes that can also have a matching constructor, and even if you additionally delete the copy constructor for the type of b).
I don't know the technical name of such a statement, so I'm not sure how to search for it in cppreference or StackOverflow. How does the compiler parse this type of statement in general, and where is it documented?
--
Re: duplicate marking. I don't see how they've addressed this construct. I already know auto uses template type deduction, that doesn't clarify anything in this case.
How is auto a(b); parsed in C++?
Depends on what b is. If b is a type, then this is a declaration of function with name a with deduced return type and a single argument of type b.
If b is not a type, then this defines a variable by the name a whose type is deduced from the initialiser.
where is it documented?
The authoritative documentation is the standard document. The standard sections [dcl.type.auto], [dcl.ambig.res], [dcl.fct], [dcl.init] should be relevant.
There are also websites that offer the documentation in (arguably) more approachable manner.
This should also be covered by recent (as in, anything since 2011) introductory C++ books.
and even if you additionally delete the copy constructor for the type of b
I doubt this. Create a mcve.
This question already has answers here:
Function Returning Itself
(10 answers)
Closed 3 years ago.
I would like to know how to declare a function type that returns a function of the same type using typedef in C++.
While watching a Golang talk given by Rob Pike on lexical scanning, I came across the following code snippet,
type stateFn func(*Scanner) stateFn
This is the exact behavior that I would like to replicate in C++.
I have tried using the following type definition,
typedef state_fn state_fn(Scanner &);
But this gives me the error function returning function is not allowed.
Is it possible at all to do something like this? If not, how do I do something similar?
You cannot return functions in C++. See [dcl.fct]p10:
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things.
However, you can return some form of callable (that may be wrapping a function of the same type).
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 4 years ago.
I have a class called "Complex" which is intended to represent complex numbers. I have defined an empty default constructor for the class that only prints a message to the screen.
When I try to create an object of the class in the main function as follows:
Complex c1();
The compiler(I am using BorlandC) doesn't give a syntax error but it doesn't create the object. How does the compiler interpret this line?
When you write this:
int foo();
…it declares a function called foo that returns an int.
When you write this:
Complex c1();
…it declares a function called c1 that returns a Complex.
Lose the ().
Contrary to popular belief, this is not quite "the most vexing parse", but it is close.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Do the parentheses after the type name make a difference with new?
So I had in my main:
Class* pC = new Class;
It was working as
Class* pC = new Class();
I realized just today that I had omitted the parentheses (so I was hit by the "opposite" of the most vexing parse in a way).
My question: Are these two forms equivalent ?
If the class has a default constructor defined, then both are equivalent; the object will be created by calling that constructor.
If the class only has an implicit default constructor, then there is a difference. The first will leave any members of POD type uninitialised; the second will value-initialise them (i.e. set them to zero).