I know the questions seems ambiguous, but I couldn't think of any other way to put it, but, Is it possible to do something like this:
#include<iostream>
class wsx;
class wsx
{
public:
wsx();
}
wsx::wsx()
{
std::cout<<"WSX";
}
?
Yes, that is possible. The following just declares wsx
class wsx;
That kind of declaration is called a forward declaration, because it's needed when two classes refer to each other:
class A;
class B { A * a; };
class A { B * b; };
One of them needs to be forward declared then.
In your example,
class wsx; // this is a class declaration
class wsx // this is a class definition
{
public:
wsx();
}
So yes, by using class wsx; it is possible to declare a class without defining it. A class declaration lets you declare pointers and references to that class, but not instances of the class. The compiler needs the class definition so it knows how much memory to allocate for an instance of the class.
This is the definition of the class
class wsx
{
public:
wsx();
}
This is the definition of the constructor
wsx::wsx()
{
std::cout<<"WSX";
}
THis is a forward declaration that says the class WILL be defined somewhere
class wsx;
Yes. But it is not possible to define a class without declaring it.
Because: Every definition is also a declaration.
You did define the class. It has no data members, but that's not necessary.
I'm not sure what you mean. The code you pasted looks correct.
Related
I have a public header that has class X. X has a private member of nested type U::V. As I understand, normally, you just forward declare the types but I cant forward declare nested type. U::V is in a private header so I cannot #include them from a public header. What do I do to have X know of class U::V?
Summary of my code:
// in include/mylib/box.h
class X {
public:
X();
//...
private:
U::V stuffs; // how do I have this declaration work?
};
// in some private file
class U {
class V{
// ..
};
};
What do I do to have X know of class U::V?
Only way to have a member of type U::V in X is to define the type U::V before defining X.
You can avoid storing the member directly by using the PIMPL idiom. In short, you would store a pointer to a forward-declared type.
This question was answered by Adam Rosenfield here.
You'll have to un-nest at least one of the nested classes
I just realized this happens because I got an incomplete class definition, not because it's a nested class. Thanks, everyone.
Is it possible to separate class declaration from its definition? Of course it is, but what if I want to have an object of this class before the actual definition of it? Consider the following example:
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File mFile;
};
It's obvious that it will not compile. I would have to define the Mp3_File class inside the ID3_Reader class. It's not a problem when I have just two classes. What if there would be like five of them? My code would become pretty messy. To avoid this problem I would have to separate the class declarations from their definitions. How can I achieve that? Remember that I need an instance of the Mp3_File class inside the ID3_Reader class.
The reason why I'm using nested classes is because I don't want some other programmer to use the Mp3_File class. I used "protected" keyword because I will create classes based on the ID3_Reader class.
You can achive this by using a pointer like the other guys answered:
class Mp3_File; // forward declaration of class Mp3_File
class ID3_Reader{
public:
// code omitted for brevity
protected:
Mp3_File *mFile;
};
Or you can declare the constructor of class Mp3_File private and declare class ID3_Reader friend of class Mp3_File:
class Mp3_File {
Mp3_File() {} // constructor is private
friend class ID3_Reader;
};
class ID3_Reader{
public:
// code omitted for brevity
protected:
Mp3_File mFile;
};
auto main() -> int {
ID3_Reader r;
Mp3_File m; // Error Mp3_File constructor is private!
return 0;
}
Thus, other people won't be able to use Mp3_File while you can use it in the scope of class ID3_Reader.
It won't compile because the compiler doesn't know how much memory that Mp3_File class will use. If you change it to a pointer
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File *mFile;
};
that compiles just fine (a pointer has a fixed size - http://ideone.com/VmmXfK).
I suggest using a pointer instead of a complete member variable and initialize/deinitialize it in the ctor/dtor.
I don't see another way of doing it without changing the "nested classes" design.
You can achieve that by using pointers. Recall that although you must have a full class to define a variable, a simple forward declaration is good to define a pointer:
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File *mFile;
};
Unfortunately, this puts you on the hook for managing the memory for the nested class, but it does hide all of the internals of the class from outside programmers.
Instead of defining mFile as an instance of Mp3_File, define it as a pointer to an Mp3_File. That way you won't need to know the definition in the header file. Or better yet - use a smart pointer. You will then need to create the real instance by using new in the class constructor and delete it in ID3_Reader's destructor.
If you wish to stay with your current syntax to access mFile from outside of the class, dereference it inside the accessor function:
Mp3_File& getMp3(){ return *mFile; };
Then - if Mp3_File has an overloaded operator() (or any other overloaded operator as a matter of fact), you won't need to dereference it every time manually.
You can make your class a class template to work around this restriction: for class templates the definition of the nested type needs to be visible at instantiation time, not while looking at the definition of the class template. You might want to use a typedef to actually name the used instantiation to avoid the need to have a trailing <>. Here is a quick demo:
template <typename = void>
class ID3_ReaderT {
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File mFile;
};
typedef ID3_Reader<> ID3_Reader;
template <typename T>
class ID3_ReaderT<T>::Mp3_File {
};
int main()
{
ID3_Reader reader;
}
Of course, it still means that every user of ID3_Reader needs to see the definition of the nested type. If you want to avoid that, your option is on level indirection, i.e., using a pointer as was already stated by multiple answers.
Is there a way to explicitly declare a base class as abstract in C++?
I know that I can create a pure virtual function in the class which will implicitly declare a class as abstract. However, I don't want to have to create a dummy function just to define in in derived classes.
I could also make the constructor protected, which would prevent the instantiation of the object, but that doesn't actually mark the class as abstract.
So, is there a way to do this? (I am using C++11, if that added a way to do this, but I didn't find anything that looked right)
You can make the destructor pure-virtual. Since you always need a destructor, there's no additional mental cost:
struct Foo
{
virtual ~Foo() = 0;
};
inline Foo::~Foo() { }
(You do of course need an implementation of the destructor, so you have to provide one out-of-line.)
You can still make the destructor protected, which is good practice following the "make non-leaf classes abstract" rule.
Example:
struct Bar : Foo { };
// Foo f; // Error, Foo is abstract
Bar b; // OK
I like Kerrek's answer. That way the class cannot be instantiated and therefore is abstract.
However, it still isn't obviously clear that the class is abstract unless you scan through the entire declaration of the class and see that the destructor is virtual.
Another idea I had is you could create a pre-processor definition for the word "abstract" using #define. This way you could do something like the following:
abstract struct Foo {};
which would be no different than
struct Foo {};
The problem I see with this is that this doesn't force the class to be abstract, so you could use a macro to also declare the virtual destructor. Something like:
#define ABSTRACT_CLASS(class_name) \
class class_name { \
virtual ~class_name() = 0; //
And then use it like so:
ABSTRACT_CLASS(Foo) {
// class declaration
};
Which would be turned into:
class foo {
virtual ~class_name() = 0; // {
// class declaration
};
Disclaimer: My macro might be slightly off. I'm not sure if it'll actually paste class_name with the ~ and the () touching the variable name. Also, I'm not sure if I'd do this myself, it's not the most beautiful solution, especially commenting out the brace since that wouldn't work if you put it on the next line. But you asked how you could mark something as abstract and I gave it to you!
Is there a way to explicitly declare a base class as abstract in C++?
No, there is not. A class is abstract only if it has at least one abstract method declared in it. If you do not want your base class to be instantiated directly, then a protected constructor is a good choice.
This may seem weird but I have a problem in one of my programs where I have a class A which needs a variable of class B inside it, and the class B needs a pointer to class A inside it, so that I can determine which class is attached to what....
I get errors because in class A it says that the class B is not defined yet, and in class B it says class A isn't defined yet...
Both of my header files which contain the separate classes include each other and I have tried to forward declare my classes e.g. class A; class B; but I get compiler errors such as:
error C2079: 'CFrame::menu' uses undefined class 'CMenu'
I need a pointer to class A in class B because I want to pass it to another class later on.
You need to declare A before you define B:
class A; // declaration of A
class B // definition of B
{
A* foo;
// ...
};
class A // definition of A
{
B bar;
// ...
};
This kind of declaration is often referred to as a forward declaration.
First of all, consider redesigning your classes. Circular dependencies are bad practice, and chances are that you could avoid this altogether with a more elegant class design.
That said, you can get around the problem using forward references (at which point, you need to use pointers or references) -
class B;
class A
{
B *pPtr;
};
class B
{
A typeA;
};
You may be able to avoid forward declaration by simply specifying what a "B" is:
class A
{
public:
class B* pB;
};
class B
{
public:
A a;
};
If you're having problems with this, it may be because you're including implementation along with your declarations. If you separate the implementation and the header, you might have fewer problems in this scenario.
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.