If I have a nested class like so:
class MyClass
{
class NestedClass
{
public:
// nested class members AND definitions here
};
// main class members here
};
Currently, the definitions of MyClass are in the CPP file but the definitions for NestedClass are in the header file, that is, I cannot declare the functions/constructors in the CPP file.
So my question is, how do I define the functions of NestedClass in the cpp file? If I cannot, what is the reason (and if this is the case, I have a vague idea of why this happens but I would like a good explanation)? What about structures?
You can. If your inner class has a method like:
class MyClass {
class NestedClass
{
public:
void someMethod();
};
// main class members here
};
...then you can define it in the .cpp file like so:
void MyClass::NestedClass::someMethod() {
// blah
}
Structures are almost the same thing as classes in C++ — just defaulting to 'public' for their access. They are treated in all other respects just like classes.
You can (as noted in comments) just declare an inner class, e.g.:
class MyClass {
class NestedClass;
// blah
};
..and then define it in the implementation file:
class MyClass::NestedClass {
// etc.
};
Related
Is there any way to redeclare a class to define methods which where only declared this far?
Eg. something like:
class A
{
void a();
void b() {}
}
class A
{
void a() {}
}
instead of
class A
{
void a();
void b() {}
}
A::a() {}
The reason is I created a lot of code with methods defined inside the class defintion, without using headers. I do not had cyclic references up to now, but recently there is need to. I don't like to define bunches of methods by the Type::method syntax, as only very few methods have to be known before the latter definition of the class.
So I like somewhat like a backward declaration, declare or define only a few methods before for cyclic references and define the whole class later.
No, there is no way to redefine a class.
According to the C++ language standard the class definitions is:
class-specifier:
class-head { member-specification_opt }
The standard explicitly says that member specification should be complete within class definition:
Members of a class are data members, member functions (9.3), nested types, and enumerators. The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere.
Also the standard gives example of redefinition of class:
struct S { int a; };
struct S { int a; }; // error, double definition
is ill-formed because it defines S twice.
Unfortunately there is no way to declare the class again once it is Closed with }.
Only thing you can do is you can inherit and define the method.
class B : public A { a() {} } ;
Is it somehow possible, to accomplish the following:
x.hpp - this file is included by many other classes
class x_impl; //forward declare
class x {
public:
//methods...
private:
x_impl* impl_;
};
x.cpp - the implementation
#include <conrete_x>
typedef concrete_x x_impl; //obviously this doesn't work
//implementation of methods...
So basically, I want the users to include the file x.hpp, but be unaware of the conrete_x.hpp header.
Since I can use concrete_x only by a pointer and it appears only as a private data member, a forward declaration should be enough for the compiler to know how much space to prepare for it. It looks quite like the well-known "pimpl idiom".
Can you help me with this?
PS. I don't want to use a void* and cast it around..
Actually, it's even possible to completely hide from the user:
// Foo.hpp
class Foo {
public:
//...
private:
struct Impl;
Impl* _impl;
};
// Foo.cpp
struct Foo::Impl {
// stuff
};
I would just like to remind you that:
you will need to write a proper destructor
and thus you will also need a proper copy constructor, copy assignment operator, move constructor and move assignment operator
There are ways to automate PIMPL, at the cost of some black magic (similar to what std::shared_ptr does).
As an alternative to the answer from #Angew, if the name concrete_x should not be made known to users of class x, you could do this:
in x.hpp
class x_impl;
class x {
public:
x();
~x();
//methods...
private:
x_impl* impl_;
};
in x.cpp
#include <concrete_x>
class x_impl : public concrete_x { };
x:x() : impl_(new x_impl) {}
x:~x() { delete impl_; }
This will only work when the forward declaration declares the actual name of the class. So either change x.hpp to:
class concrete_x;
class x {
public:
//methods...
private:
concrete_x* impl_;
};
or use the name x_impl for the class defined in the header <concrete_x>.
That's what interfaces are for. Define an interface (pure virtual class) in your shared header file and give it to users. Inherit your concrete class from the interface and put it in the non-shared header file. Implement the concrete class in the cpp file (you can even define the concrete class inside the cpp).
I came across this code.
class SomeClass::OtherClass : public BaseClass
{
// stuff in here
}
SomeClass is a class, so maybe OtherClass is a class that exists inside the scope of SomeClass? I've just never seen it done this way.
So, is that what it means?
maybe OtherClass is a class that exists inside the scope of SomeClass?
Give yourself a checkmark. That is what it means.
This is used to subsequently define OtherClass after it was declared inside SomeClass:
class SomeClass {
class OtherClass;
OtherClass* GetOtherClassInstance() { ...}
};
class SomeClass::OtherClass {
}
One might do this if the inner class only makes sense in the context of the exterior class.
class Vector {
class Iterator;
Iterator* GetStart();
};
class Vector::Iterator {
details.
}
As mentioned elsewhere, the pimpl idiom is an excellent use of inner classes with deferred definition.
It means that OtherClass is an inner class of SomeClass. It had better already have been declared there. Works nice for the pimpl idiom:
struct my_object {
...
private:
struct my_impl;
my_impl * pimpl;
};
// in a cpp file...
struct my_object::my_impl {
...implementation details of my_object
};
I think SomeClass is namespace in which OtherClass resides
class BaseClass {};
namespace SomeClass
{
class OtherClass;
};
class SomeClass::OtherClass : public BaseClass
{
// stuff in here
};
some class is a name of base class and other class is a derived class which link the inside of derived class and after the colon derived class link the base class.
In your question the answer is two base class and one derived class are mention.
(In C++) I have a class whose structure is declared in a header file. That header file is included in lots of source files, such that when I edit it I need to recompile lots of files.
The class has a set of private functions which are only called in one source file. Currently they are declared in the class structure in the header file. When I add a new function of this type, or edit the arguments, it therefore causes recompilation of lots of files. I would like to declare the functions somewhere else, such that only the file that defines and calls them is recompiled (to save time). They still need to be able to access the internal class variables, though.
How can I achieve this?
Use the pImpl idiom - Your visible class keeps a pointer to the real class and forwards calls to public member functions.
EDIT: In response to comments
// Foo.h:
class FooImpl; // Do *not* include FooImpl.h
class Foo {
public:
Foo();
~Foo();
//.. also need copy ctor and op=
int bar();
private:
FooImpl * Impl;
};
// FooImpl.h:
class FooImpl {
public:
int bar() { return Bar; }
private:
int Bar;
};
// Foo.cpp:
#include "FooImpl.h"
Foo::Foo() { Impl = new FooImpl(); }
Foo::~Foo() { delete Impl; }
int Foo::bar() { return Impl->bar(); }
Keep the actual implementation of your class in FooImpl - Foo should have copies of the public members of FooImpl and simply forward calls to these. All users will include only "Foo.h" - you can change all the private details of FooImpl without the users of Foo seeing any changes.
There is no way to declare member functions of a class outside the main class declaration. So, if you want to declare, outside of the class in question, functions that can access member variables of a particular instance of the class, then I see no alternative but to pass that instance to the function. Furthermore, if you want the functions to be able to access the private and protected variables you will need to put them in a new class and make the original class a friend of that. E.g.
header.h:
class FooImpl;
class Foo {
public:
int bar();
friend class FooImpl;
private:
int var;
}
impl.cpp:
#include "header.h"
class FooImpl {
public:
int bar(Foo &);
}
int FooImpl::bar(Foo &foo) {
return foo.var;
}
int Foo::bar() {
return FooImpl::bar(*this);
}
Are you looking for Compiler Firewall, a.k.a. PIMPL?
Create an abstract base class which contains only the public functions and reference this in your headers. Create your real class as an implementation somewhere else. Only source files which need to create your class need to see the implementation class header.
I have put several instances of class b in class a but this causes an error as class a does not know what class b is.
Now I know I can solve this problem by writing my file b a c but this messes up the reachability as well as annoys me. I know I can prototype my functions so I do not have this problem but have been able to find no material on how to prototype a class.
does anyone have an example of class prototyping in c++.
as there seems to be some confusion let me show you what i want
class A
{
public:
B foo[5];
};
class B
{
public:
int foo;
char bar;
}
but this does not work as A cannot see B so i need to put something before them both, if it was a function i would put A(); then implement it later. how can i do this with a class.
You can declare all your classes and then define them in any order, like so:
// Declare my classes
class A;
class B;
class C;
// Define my classes (any order will do)
class A { ... };
class B { ... };
class C { ... };
You're looking for declarations.
class A;
class B {
A MakeA();
void ProcessA(A a);
};
class A {
B bs[1000];
};
If you forward declare a class, you can
declare functions taking and returning it or complex types made of it
declare member variables of pointer or reference to it
This basically means that in any case which doesn't end up with instances of A inside B and vice versa, you should be able to declare and define any interface between A and B.
The usual way to resolve circular dependencies is to use a forward declaration:
// Bar.h
class Foo; // declares the class Foo without defining it
class Bar {
Foo & foo; // can only be used for reference or pointer
};
// Foo.h
#include <Bar.h>
class Foo {
Bar bar; // has full declaration, can create instance
}
You can provide a full declaration and definition in another file. Using the forward declaration, you can create pointers and references to the class, but you cannot create instances of it, as this requires the full declaration.
class b;
class a {
public:
b * inst1;
};
class b{
....
};
Is this what you needed ?