After the example
class foo{
other* bar;
...
};
class other{
...
}
… which (1) uses an undeclared name, and (2) lacks a crucial semicolon, you ask
” Why isn't this possible then? (Does the standard forbids that explicitly? for what?)
The Holy Standard requires that every name must be declared before it's used.
Note that in a given C++ implementation, even data pointers can be of different sizes (void*
is guaranteed to be able to hold any data pointer), not to mention function pointers.
An alternative to declare-before-first-use requirement could be to adopt a default, like with implicit int
in the early C days. E.g. the compiler could assume that other
was a class type. But that would not be very helpful in general, and it would complicate the language.
However, in this particular case it's possible to combine the necessary minimum declaration of other
with its first use:
class foo{
class other* bar;
//...
};
class other{
//...
};
Alternatively you could use an ordinary forward declaration:
class other;
class foo{
other* bar;
//...
};
class other{
//...
};
Just so the compiler knows that other
is a class type, and not e.g. a function, or a synonym for char
or void
(pointers to these types are the largest, if there is any variability in the size of basic raw data pointers).
You then assert:
” The dummy example I posted above may seem have no real meaning. The reason why I want to do without forward declaration is that when you got a nested class, there's no forward declaration that can preserve the encapsulation.
That's wrong.
E.g. this works nicely:
class Foo
{
private:
class Other;
Other* bar;
class Other{};
public:
Foo(): bar( new Other ) {}
};
However, the shortcut with declaration in the first use, class Other* bar;
, doesn't work in this case. That's because it effectively would declare Other
as a namespace level class instead of a nested one.