I'm trying to declare class as the following:
class MyClass: MyBase;
But I can't because compiler is swearing.
error: expected ‘{’ before ‘;’ token
I'm trying to find a class name declaration to clarify this aspect. But I can't. I'm looking for this in the clause 7 (Declarations) of the c++ working draft.
If you just want to declare the MyClass class, then
class MyClass;
is enough. It tells the compiler that the class MyClass exists, and you can now declare pointers or references to MyClass.
If you want to define the class, then you need to full definition.
About standard(n3797):
9.1 Class names:
A class declaration introduces the class name... A declaration
consisting solely of class-key identifier; is either a redeclaration of
the name in the current scope or a forward declaration of the
identifier as a class name. It introduces the class name into the
current scope.
10 Derived classes:
A list of base classes can be specified in a class definition...
So, you can just tell the compiler: "Oh, I will define this class later". If you need to know the "structure" of the class then you need to define it.
Give definition in this way :
class MyClass: MyBase
{
//////
};
If you only want to declare then do in this way :
class MyClass;
Related
As a rule of thumb on forward declaration (from "API Design for C++", p. 214), I only include the header of a class if I:
use an object of that class as a data member in my own class, or
inherit from that class.
In all rest cases I just forward declare the class.
However, I recently used by accident as a data member of a class a forward declared enum class, and it compiled.
Is this indeed ok to use, or a just an accidental hack (and I actually need the header with the definition of MyEnum)?
// test.hpp
enum class MyEnum;
class A {
MyEnum myenum;
};
A forward declared enum class has a specified underlying type. If not explicitly specified it is int. Because of that the storage size of the enum is known, even if it's only forward declared, so using it as a member is not a problem.
I would like to have a class inherit from its enclosed class, as in:
class A : public A::B {
public:
class B {};
};
However, the compiler complains that A::B is not defined:
error: expected class-name before '{' token
class A : public A::B {
That is, A::B won't be usable until the definition of A is complete.
I have tried to preface the above with
class A;
class A::B;
But it doesn't help. How can I get this declared and defined correctly?
Note: Essentially, I am trying to do the opposite of this question.
At the point where you specify the inheritance, the inner class is not yet know. Thus you can't do that. But if the point is to limit the scope, then just use a namespace, e.g. call it detail or implementation.
This is not possible, there is no way to declare inner class without defining the outer class.
What is the point of the following using-declarations
using eoPop<MOEOT>::size;
using eoPop<MOEOT>::operator[];
using eoPop<MOEOT>::back;
using eoPop<MOEOT>::pop_back;
Taken from the class defined here. Surely, because eoPop<EOT> inherits std::vector<EOT>, the methods size, operator[] , back and pop_back are public there is no need for the using declaration. Are the using declaration used to force instantiation?
Although I don't know why they've decided to include those using-declarations, I can tell why the code would be ill-formed without them.
But first, repeating from a comment:
A using-declaration doesn't require the existence of the definition the nominated entity (here: it doesn't require the existence of the definition of those functions). Consider:
void foo();
int main()
{
using ::foo; // doesn't require the definition of `foo` to exist
return 0;
}
If a class template gets implicitly instantiated, the declarations of its member functions are instantiated, but not their definitions (as per [temp.inst]/1). The base classes of a class template are also instantiated if said class template is implicitly instantiated (which in turn leads to the instantiation of the declarations of the member functions of those base class templates). Therefore, the using-declaration doesn't help with instantiation.
An effect of those using-declarations is that the names declared are visible for non-dependent name lookup. As per [temp.dep]/3
In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup [...].
In the linked code, we find for example i<size(). The name size here is non-dependent, therefore the base class scope is not searched, and eoPop < MOEOT > :: size would not be found without the using-declaration.
Another reason to use using-declarations is if you want to overload a member function of a base class. If you don't use the using-decl, the member function in the derived class simply hides every overload (with the same name) in the base class. As far as I can see, this is not used in the linked code.
Today, I was curious to find some of differences between a structure and a class, in C++. So, I found some of the differences:
In a structure, by default members are public while private in class.
Inheritance in case of a structure is public by default, while private in case of class.
Classes can take part in templates, while structures cannot.
click here to see that a struct cannot be used in place of class in case of template.
http://ideone.com/p5G57
template<struct T> void fun(T i)
{
cout<<i<<endl;
}
int main()
{
int i=10;
fun<int>(i);
return 0;
}
It gives the errors:
prog.cpp:4: error: ‘struct T’ is not a valid type for a template constant parameter
prog.cpp: In function ‘void fun(T)’:
prog.cpp:4: error: ‘i’ has incomplete type
prog.cpp:4: error: forward declaration of ‘struct T’
prog.cpp: In function ‘int main()’:
prog.cpp:12: error: no matching function for call to ‘fun(int&)’
However, if struct is replaced with class, it works perfectly. see here: http://ideone.com/K8bFn
Apart from these above differences, when I replace class with struct in my code, the code works perfectly without making any further changes.
Now, I want to know, are there more differences, that I am missing and I should know?
There's no other difference, but the third one you specify isn't correct:
Class can take part in template while structures cannot.
In case of templates, the class keyword is just syntactic sugar, it doesn't mean the type has to be an actual class. Generally, programmers prefer typename for basic types and class for classes or structs, but that's just by convention.
Other than that, you can use both class and struct to specialize templates.
There are two main differences:
In absence of an access-specifier for a base class, public is assumed when the derived class is declared struct and private is assumed when the class is declared class.
Member of a class defined with the keyword class are private by default. Members of a class defined with the keywords struct or union are public by default.
A struct is just a class with all members public by default.
According to The C++ Programming Language (3rd ed.), section 10.2.8:
By definition, a struct is a class in which members are by default
public; that is
struct s{ ...
is simply shorthand for
class s { public: ...
Then he goes on to say:
I usually prefer to use struct for classes that have all data public.
I think of such classes as "not quite proper types, just data
structures."
Edited per the comments:
In section 15.3.2 it says:
The access specifier for a base class can be left out. In that case,
the base defaults to a private base for a class and a public base
for a struct.
I just stumbled a c++ code with a calling of a class name in the upper part of the header file for example
class CFoo;
class CBar
{
....
};
My question is, what is class CFoo for?
Thanks alot!
This is called a forward declaration. It means that there IS a class named CFoo, that will be defined later in the file (or another include). This is typically used for pointer members in classes, such as:
class CFoo;
class CBar {
public:
CFoo* object;
};
It is a hint to the C++ compiler telling it not to freak out that a type name is being used without being defined, even though it hasn't seen the full definition for CFoo yet.
It's called a forward declaration.
http://en.wikipedia.org/wiki/Forward_declaration
class CFoo;
Is just a declaration that the class exists; even if you haven't seen the definition yet, you can still play with (CFoo *) or (CFoo &) - that is, pointers and references to CFoo.