How do I need to declare a member class? - c++

I need to use a custom exception class that's goign to be used from within member the function of the top-level class. So, it's reasonble to put the custom class as a member class. Here is the file where they're declared presently:
conductor.h:
class conductor
{
//some staff
private:
class bad_index : public std::exception
{
public:
bad_index(int);
virtual const char* what() const noexcept;
private:
int _idx;
};
};
I'm new to programming in C++ and still haven't learn how the C++ programmer're used to doing such things? Maybe we should put class bad_index as an incomplete type like that:
class conductor
{
//some staff
private:
class bad_index;
};
and make it complete and implement all member-functions in the cpp-file. What is the right way?

First of all, as bad_index is private, it can't be referenced outside the class, so it can't be used in exception handlers other than catch(...). If it's not really needed (that is, the exception is made only for internal use), perhaps it's enough to not make it a nested class but to define bad_index in the implementation file in namespace { ... }.
In case that bad_index is actually public, technically you can declare it in .h file and define in .cpp file, but it will again be unusable in catch clauses of class users, because you can't catch an exception of incomplete type even by reference, all you can do to catch it is again catch(...).

If the class is not part of public interface of your top level class then it makes sense to put al little information about it into the header file as possible and forward declaration does that job well. However if all the code that uses that exception is in one cpp file then you could as well avoid mentioning it in the header at all and declare in an anonymous namespace inside the cpp file.

Related

What does class pointer* mean?

I got this syntax I don't really understand:
class USphereComponent* ProxSphere;
I think this means create a class, but is this class a pointer?
But the result is just creating an object called ProxSphere from an existing class USphereComponent.
What does this syntax actually mean, and what is its usage?
class Someotherclass; // That has not been defined yet
class HelloWorld
{
Someotherclass* my_pointer;
};
Or an alternative:
class HelloWorld
{
class Someotherclass* my_pointer;
};
The first one is obviously the correct one if you have multiple pointers (or references) to such class that has not been defined yet.
Is the second better? (I don't know) if you only need to do it once, otherwise doing
class HelloWorld
{
class Someotherclass* my_pointer;
class Someotherclass* my_pointer2;
class Someotherclass* my_pointer3;
void func(class Someotherclass* my_pointer, class Someotherclass& my_ref);
};
may not be the best.
Jts's answer is correct. I'd like to add a use case for it:
This is mostly used when you have a circular class dependency.
Like:
class A { B* binst; };
class B { A* ainst; };
That wouldn't compile since B isn't previously known.
Therefore you would first declare class B.
class B;
class A { B* binst; };
class B { A* ainst; };
Or as mentioned, you can use syntactic sugar:
class A { class B* binst; };
class B { A* ainst; };
Such a dependency might be a code smell. It also might be ok or even necessary. If you have it, you should carefully think if you can't do it in some other yet convenient way.
That particular syntax is called a "forward declaration". It is used to declare a type that has not been defined yet.
This is basically telling the compiler "There exists a class type named USphereComponent that you haven't seen yet that will come up later in the code. Please don't yell at me if you see pointers of that type". This allows you to declare pointer and reference for that forward-declared type.
Writing:
class USphereComponent* ProxSphere;
Is really just the equivalent of writing this:
class USphereComponent;
USphereComponent* ProxSphere;
The only difference with the second syntax, is that you only need to forward-declare the type once when you do it like this class USphereComponent;, otherwise you need to use the first syntax and add the class keyword before each usage of USphereComponent.
There are two main reasons why you may want to use a forward declaration:
This is probably the most common usage of forward-declaration in Unreal Engine. In header (.h) files, forward-declaration allows you to use pointer of classes for which you did not #include the corresponding header file. In our particular example that means that forward-declaring USphereComponent means that we don't need a #include "SphereComponent.h" statement (if we're just trying to pass a USphereComponent around that is).
Typically when that happens, the #include statement is simply done in the .cpp file. There are mainly two advantages of reducing the number of includes in your header files:
Compilation times are faster. Mind you, this mostly has significant impact on a codebase as big as Unreal's.
This reduces the number of public dependencies of you module (by making them "private" since your includes are now in your .cpp). This makes your module easier to be depended upon and also makes its interface cleaner.
Like other answers have said, forward-declaration can be used to break circular dependencies when you have two types that depends on each other in the same file:
class B;
class A
{
B* foo;
};
class B
{
A* bar;
};

How to limit a function scope in the same file as it is defined in c++?

I have public member functions which are calling private member function. I want to limit the scope of the private member function within the file where definition of private member function is available. In C, I used static before the function name to limit its scope within the file, how do I achieve it in C++.
class Base
{
public:
void XYZ1(void);
void XYZ2(void);
private:
void fun(void);
};
void Base::XYZ1(void)
{
fun();
}
void Base::fun(void)
{
// do something;
}
Now if the member function XYZ2 is defined in some other .cpp file , it should not be allowed to call fun() from it. Basically restrict the fun() function to file scope.
In a1.cpp
void Base::XYZ2(void)
{
fun();// this should result in some error saying fun() is not defined in its scope.
}
I want to limit the scope of the private member function within the file where definition of private member function is available.
A private member function cannot be used by another class or function unless they are granted friend-ship by the class. In that sense, the scope in which the function can be called is already limited.
Having said that, any member function of the class or any class or function that has been granted friend-ship by the class will be able to call the private member function.
The only way to prevent that function from being called outside the file in which it is defined is to make it a non-member static function in the .cpp file. or put it in an anonymous namespace in the .cpp file.
Now if the member function XYZ2 is defined in some other .cpp file ,
it should not be allowed to call fun() from it. Basically restrict the
fun() function to file scope. In a1.cpp
You can put the function in an anonymous namespace (in the cpp file where used). The linkage will become internal, and the name won't be available for access from any other file. One can get the same effect when making the function static (in the cpp file).
If you need to access internal/private members, you could use a nested class who's implementation is defined in the associated cpp file:
//h
class Nesting
{
//...
private:
struct MyPrivateFunctions;
};
//cpp
struct Nesting::MyPrivateFunctions
{
static void f1(Nesting& this);
static void f2(Nesting& this);
//etc...
};
I've passed Nesting as parameter that MyPrivateFunctions may access its private members (since it is nested, this is permitted).
Note that this is very similar to the Impl trick mentioned elsewhere, but it also allows independent member function definitions in other units, and it does not need instantiation.
Most people are suggesting you to use anonymous namespace in C++. But, this would only be feasible if you wanted to do something like, declaring a global variable/function which is supposed to be used strictly inside the file under which it is defined.
We cannot use namespace within the class as per C++ standards, for which you may want to take a look at this discussion: Why can't we declare a namespace within a class?
I used static before the function name to limit its scope within the file.
This worked for you but the understanding here is wrong as static was never intended to be used as scope specifier, its a storage specifier and its lifetime is throughout the program life. You can still access the static variable from other files in several ways, however the compiler here does not provide an externally visible linker symbol and thus cannot be accessed by other translation units / files.
As per the public member functions are concerned they should be allowed to use this private function from whichever file it is defined in. So that the relation between the class member functions are not destroyed. I suppose you would now stop treating static as scope specifier :)
Or you can use the good old Impl- trick if you do not want to show the "hidden" functions of a class to the outside. Private functions are still listed in the header file, after all.
// Foo.h
class FooImpl; // forward declearation
class Foo
{
FooImpl *m_pImpl;
public:
Foo(); // Default constructor (and any other) create instance of FooImpl.
~Foo();
};
// Foo.cpp
class FooImpl
{
// members of hidden types, secrets, methods, ... anything you do not want to show to users of class Foo.
};
Foo::Foo() : m_pImpl(new FooImpl()) {}
Foo::~Foo()
{
delete m_pImpl; m_pImpl = nullptr;
}
As can be seen, with the impl trick you cannot only hide functions, but also data members of a class and type dependencies which would be incurred if the members were part of Foo class.
A way to solve this problem is by using a so called 'facade'. Basically, you have two classes: The first class has the private method which you want to hide, where as the second class implements a wrapper which just provides the methods you want to be accessible. The second class wraps an instance of the first. That's how the whole trick works.
https://en.wikipedia.org/wiki/Facade_pattern

confused on forward declarations

#pragma once
#include "Player.h"
class Player;
//class SmallHealth;
const int kNumOfCards = 3; //for Player class also
const int kCardLimit = 3;
class Cards
{
private:
protected:
int turnsInEffect;
Player *owner;
public:
Cards()
{turnsInEffect = 1;}
void AssignOwner(Player &player)
{
owner = &player;
}
virtual void PlayCard()
{}
virtual ~Cards(void)
{}
};
class SmallHealth : public Cards
{
public:
void PlayCard()
{
turnsInEffect = 1;
owner->SetHealth(owner->GetHealth() + 5);
//check if health goes over
if(owner->GetHealth() > owner->GetHealthLimit())
{
owner->SetHealth(owner->GetHealthLimit());
}
turnsInEffect--;
}
};
I thought by declaring class Player I wouldn't get these errors:
error C2027: use of undefined type 'Player
see declaration of 'Player'
error C2227: left of '->SetHealth' must point to ...
Checking on error 2027, seems I have to explicitly have the whole class before the Cards class, but I thought the forward class declaration would make it unnecessary. How I have it set up is that Cards class is created and assigned a subclass by the Player class and stored in the Player class. The subclasses that inherit the Cards class will call upon the functions of the Player class. I'm having a tough time making sure the 2 classes identify each others classes.
In that case, a forward declaration of a C++ class will just tell the compiler that the type you're using is a class.
This is often useful for headers, as you only need to know that the type is a class. Including the class' header would take more compile time.
But in the implementation, it's different. With a forward class, the compiler will not know about its members, methods, etc.
For that, you need to include the header file of the class.
For instance, with only the forward class, you can't do that:
owner->GetHealth();
As there is no way for the compiler to know the GetHealth method exists in your Player class, with just a forward class.
Note you may also have a problem in your AssignOwner method, as you implement it using your header. I'm a bit rusty on C++, as I'm doing C most of the time, but I think you should try declaring only the prototype in the class header, and implement the actual method in your implementation file, after having included the correct header file.
Forward declarations allow you to declare a pointer or reference to a type, but to actually use the pointer or reference you must have the full class definition. You also need the full definition for a member or local variable of the class type.

Declare a C++ class without defining it in the current translation unit

It is possible to declare a class without defining it (forward declaration) as long as it is defined later on within the translation unit. In the case of functions, one can declare a function without defining it within the translation unit, and the linker will link it to its definition in a different translation unit. Is it possible to do the same with class declarations?
(if this is not possible, is there any use to a forwardly declared class without a definition in the current TL, or is that always an error?)
something like this, except this doesn't compile:
mymain.cpp:
class myclass; // declare without defining
myclass::myclass();
void myclass::barf();
int main() {
myclass *m = new myclass();
m->barf();
return 0;
}
myclass.cpp:
#include <iostream>
class myclass { // define the implementation
public:
myclass();
void barf();
};
myclass::myclass() { } //empty constructor
void myclass::barf() {
std::cout << "barfing\n";
}
It is possible to forward-declare a class, but only pointers and references to forward-declared classes can be used. You can't use an actual object of a forward-declared class because the compiler doesn't know enough about it; in particular it doesn't know how large the object is or what its members are. Trying to forward-declare member functions (as you have done) won't work because the syntax of the forward declaration doesn't allow you to specify whether the functions are virtual or non-virtual (or perhaps inherited from some base class).
It is not often useful to forward-declare a class in a source file, but it can be useful in a header file. In particular it's common to forward-declare a class in a library's public header file and use pointers to that type as opaque handles. The class definition remains private to the library but user code can pass around pointers to objects of that class without ever knowing what the class's implementation looks like. This works particularly well when the pointers are smart pointers.
You can, but only if you use exclusively pointers or references to that class. But you can't use code referring to that class' members (variables or methods). You can only use it to declare pointer variables to that class.
I would suggest you create a myclass.h header file with myclass' full declaration, and include that header in mymain.cpp.
You can only do that through hacks.
The declare before use rule doesn't hold within a class (see here).
Otherwise you can do that by declaring your function as a template function, whose template parameter is of myclass (in your example).
The only non-hack way is to define the class (ie. by including the header file its defined in).

hiding inner class implementation using namespace

I am developing a library and a would like to provide my users a public interface separate from the real implementation that is hidden in a namespace. This way, I could change only the class HiddenQueue without changing myQueue that will be exposed to users only.
If I put the C++ code of HiddenQueue in the myQueue.cpp file the compiler complains saying _innerQueue has incomplete type. I thought that the linker was able to resolve this. What I am doing wrong here?
// myQueue.h
namespace inner{
class HiddenQueue;
};
class myQueue{
public:
myQueue();
);
private:
inner::HiddenQueue _innerQueue;
};
///////////////////////////
// myQueue.cpp
namespace inner{
class HiddenQueue{};
};
The compiler needs to know the exact memory layout of an object by looking at the header file it's defined in.
Your code says that class MyQueue has a member of type InnerQueue, which will be part of the memory layout of MyQueue objects. Therefore, to deduce the memory layout of MyQueue it needs to know the memory layout of InnerQueue. Which it does not, because you say "oh well, it's defined elsewhere".
What you are trying to do is closely related to "the PIMPL idiom"/"compiler firewall" technique.
To solve the problem, you must either include HiddenQueue.h in your header or declare _innerqueue as a pointer:
class myQueue {
public:
myQueue();
private:
inner::HiddenQueue* _pinnerQueue;
};
Using a pointer is possible because a pointer has a known memory size (dependent on your target architecture), therefore the compiler doesn't need to see the full declaration of HiddenQueue.
To be able to make a member of a class, you need to have a definition for it and not only a declaration. (A declaration is enough for a pointer or a reference to the class).
You need to provide pointer to _innetQueue rather then the object itself:
std::auto_ptr<inner::HiddenQueue> _innerQueue;
Search form pimpl ideom or d-pointer