When I have a header file like this:
#ifndef GAMEVIEW_H_
#define GAMEVIEW_H_
#include <SDL/SDL.h>
class GameView
{
public:
GameView();
virtual ~GameView();
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
#endif /* GAMEVIEW_H_ */
I need to create a .cpp file like this:
#include "GameView.h"
GameView::~GameView()
{
}
GameView::GameView()
{
}
This is a bit stupid. Just a .cpp file for an empty constructor and deconstructor.
I want to implement that method simply in the header file. That is much cleaner.
How to do this?
You can define your constructor and destructor (this is the proper term, use this instead of deconstructor) inline:
class GameView
{
public:
GameView() {}
virtual ~GameView() {}
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
I want to implement that method simply in the header file. That is much cleaner.
So be it.
// ...
GameView() { }
virtual ~GameView() { }
// ...
You don't even need to write this. The compiler provides a default constructor itself. The only thing you need is the destructor because it's not virtual by default.
In case you heard you need to define these in the .cpp file - this is sometimes needed if you have smart pointers in your class as members. A rule of thumb is that when you have smart pointers to in your class, and they point to a class that's just forward declared in the header, always provide constructors and destructors in the .cpp file where you actually define the pointed-to class. Otherwise you can get problems with deletion of incomplete classes (causing undefined behavior in many cases).
#ifndef GAMEVIEW_H_
#define GAMEVIEW_H_
#include <SDL/SDL.h>
class GameView
{
public:
GameView() {}
virtual ~GameView() {}
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
#endif /* GAMEVIEW_H_ */
I don't see your problem:
class GameView
{
public:
GameView() {}
virtual ~GameView() {}
virtual void Update() = 0;
virtual void Render(SDL_Surface* buffer) = 0;
};
And of course if the constructor does nothing, there is no need to provide it all.
Related
The users of a class need not see the private members of that class. Those members may introduce new types the users should not be aware of, requiring #include of files to declare those types. I would like to get rid of these #include. I would prefer declaring these private members of the class, in a separate .hpp file that is seen only by the implementation of the class.
Is there a way doing this ?
I'm afraid it is not possible as the client class has probably to know the size of an instance of that class, then must have access to its full declaration. This unfortunately adds useless dependances.
You would usually use the pimpl idiom for this:
// --------------------
// interface (widget.h)
class widget
{
widget();
void exampleFunction();
private:
struct impl;
std::unique_ptr<impl> pImpl;
};
// ---------------------------
// implementation (widget.cpp)
struct widget::impl
{
// implementation details
int exampleMember;
};
widget::widget() : pImpl(std::make_unique<widget::impl>()){}
void widget::exampleFunction() {
pImpl->exampleMember++;
}
A simple pattern is this.
// IFoo.h
#pragma once
class IFoo
{
public:
virtual void DoSomethingImportant() = 0;
virtual void DoSomethingElse() = 0;
};
-----------------------
// Foo.h
#pragma once
#include "IFoo.h"
#include "MessyHeaderFilesThatPullIntooMuch.h"
class Foo : public IFoo
{
private:
ComplexStructure _internals; // stuff you don't want clients to know abouve
int _x;
int _y;
public:
virtual void DoSomethingImportant() override;
virtual void DoSomethingElse() override;
};
-----------------------
// Foo.cpp
#include "Foo.h"
void Foo::DoSomethingImportant() {Your code goes here}
void Foo::DoSomethingElse() {Your code goes here}
-----------------------
// FooFactory.h
#pragma once
#include <IFoo.h>
IFoo* CreateFoo();
-----------------------
// FooFactory.cpp
#include <FooFactory.h>
#include <Foo.h>
IFoo* CreateFoo()
{
return new Foo();
}
Then the clients who want to get at an instance of "Foo" just need to #include "FooFactory.h" to obtain a new instance of Foo via the IFoo interface pointer. And they never have to see the messy internals of Foo or take a dependency on the additional header files Foo needs. They get back just the public interface of Foo that hides all the internals.
So consider I have a class with a private member variable and a private function which I do not want to define in the header file, because I want to "hide" it from the user.
How can I make this? I can not access the private variable without the declaration of the function in the header.
So what works is something like this:
// header file
class Testclass {
public:
// ...
private:
const int m_i;
void func() const;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
But I want something like this:
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
Which possibilities do I have? I read something about the PIMPL Idiom, but I am not sure if this is what I want, since it looks a bit cumbersome coding-wise.
You can have non-member helper functions in the cpp file, that the class members can use. However, they would have to pass the private variable as a parameter.
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
void func(int m_i) {
int j = m_i; //private member variable supplied by caller
}
// ...
Normally one achieves this through the PIMPL (Pointer to IMPLementation) idiom. In your header file you have:
class MainClass
{
public:
void public_function();
private:
class Impl;
Impl* impl;
};
Note that the header file does not contain the definition of the Impl class, only its declaration.
You then define that class in your cpp file and forward the calls from your public interface to the functions of the impl class:
class MainClass::Impl
{
void actualfunc()
{
//do useful stuff here
}
};
void MainClass::public_function()
{
return impl->actualfunc();
}
Apart from your indended hiding of unwanted members from your class users, the PIMPL idiom provides the additional benefit that if no changes are made to the interface of the class, the users of the class need not be recompiled.
File A.h
#ifndef A_H_
#define A_H_
class A {
public:
virtual ~A();
virtual void doWork();
};
#endif
File Child.h
#ifndef CHILD_H_
#define CHILD_H_
#include "A.h"
class Child: public A {
private:
int x,y;
public:
Child();
~Child();
void doWork();
};
#endif
And Child.cpp
#include "Child.h"
Child::Child(){
x = 5;
}
Child::~Child(){...}
void Child::doWork(){...};
The compiler says that there is a undefined reference to vtable for A.
I have tried lots of different things and yet none have worked.
My objective is for class A to be an Interface, and to seperate implementation code from headers.
Why the error & how to resolve it?
You need to provide definitions for all virtual functions in class A. Only pure virtual functions are allowed to have no definitions.
i.e: In class A both the methods:
virtual ~A();
virtual void doWork();
should be defined(should have a body)
e.g.:
A.cpp
void A::doWork()
{
}
A::~A()
{
}
Caveat:
If you want your class A to act as an interface(a.k.a Abstract class in C++) then you should make the method pure virtual.
virtual void doWork() = 0;
Good Read:
What does it mean that the "virtual table" is an unresolved external?
When building C++, the linker says my constructors, destructors or virtual tables are undefined.
My objective is for A to be an Interface, and to seperate implementation code from headers.
In that case, make the member function as pure virtual in class A.
class A {
// ...
virtual void doWork() = 0;
};
Make sure to delete any "*.gch" files if none of the other responses help you.
I want to call a method on a template class, and I need a way to ensure that method will be on my template class.
The only way I know how to ensure a method is available on a class, is to derive the class from a pure virtual base class. This creates an enormous amount of overhead, as you can see in the code below.
Obviously, the interface is extraneous and unrelated to the explicit specialization of the templated class, which is actually driving the code in main.cpp. Am I just being old fashioned and clinging onto "interfaces", or is there a modern object-oriented approach to ensuring template classes are complete?
EDIT:
To provide insight into the code below...
There is an interface, called "Interface", which has a virtual destructor and a pure virtual method called sayHi(). A inherits from Interface and implements sayHi(). A is then passed as a template into Template, which then calls sayHi() in its salutations() method. To further confuse things, a static method is the best solution for my problem. However, in order to use a base class as an interface to provide inheritance to my template class I could not have a static method, so you see two methods non-static to satisfy the virtual method and one static to satisfy my needs.
As I see it, there is no need of the interface other than to be organized in an object oriented since, and it causes a considerable amount of pain. Is there another way to get the sense of order provided by an interface, or is this type of thinking just obsolete?
main.cpp
#include "a.h"
#include "template.h"
int main (int argc, char * argv[]) {
Template<A> a;
a.salutations();
return 0;
}
interface.h
#ifndef INTERFACE_H
#define INTERFACE_H
struct Interface {
virtual
~Interface (
void
) {}
virtual
void
sayHi (
void
) const = 0;
};
#endif
a.h
#ifndef A_H
#define A_H
#include "interface.h"
class A : public Interface {
public:
A (
void
);
~A (
void
);
void
sayHi (
void
) const;
static
void
sayHi (
bool = false
);
};
#endif
a.cpp
#include "a.h"
#include <iostream>
A::A (
void
) {}
A::~A (
void
) {}
void
A::sayHi (
void
) const {
return A::sayHi(true);
}
void
A::sayHi (
bool
) {
std::cout << "Hi from A!" << std::endl;
}
template.h
#ifndef TEMPLATE_H
#define TEMPLATE_H
template <class Interface>
class Template {
public:
void salutations (void);
};
#endif
template.cpp
#include "template.h"
#include "a.h"
template<>
void
Template<A>::salutations (
void
) {
A::sayHi();
return;
}
C++ is not Java. I do not know any way to say that the class or typename must be derived from another class.
It is really duck typing. Just use the methods and compiler will throw errors if they are not present. BTW, when you write
template <class Interface>
class Template {
public:
void salutations (void);
};
Interface is here the same as T would be : it does not require that the specialization used will be a subclass of class Interface.
OK, I have been looking about but can not for the wits of me find a reason to why this should not work:
Base class (misc/interface/handler.h)
#ifndef __t__MISC_VIRTUAL_HANDLER_H
#define __t__MISC_VIRTUAL_HANDLER_H
#pragma message("Starting with 'handler.h'")
namespace t {
namespace misc {
namespace interface {
class Handler {
public:
Handler();
virtual ~Handler();
virtual int setup() = 0;
virtual int teardown() = 0;
virtual int update() = 0;
protected:
private:
};
}
}
}
#pragma message("Ending with 'handler.h'")
#endif // __t__MISC_VIRTUAL_HANDLER_H
Derived class (graphics/handler.h):
#ifndef __t_GRAPHICS_HANDLER_H
#define __t_GRAPHICS_HANDLER_H
#include "../misc/interface/handler.h"
namespace t {
namespace graphics {
class Handler: public t::misc::interface::Handler {
public:
Handler();
virtual ~Handler();
int getResolutionX() { return m_resolutionX; }
int getResolutionY() { return m_resolutionY; }
bool getFullscreen() { return m_isFullscreen; }
protected:
private:
unsigned int m_resolutionX, m_resolutionY;
bool m_isFullscreen;
}; // class Handler
} // namespace graphics
} // namespace t
#endif // __t_GRAPHICS_HANDLER_H
... which seems rather trivial.
Derived class implementation (graphics/handler.cpp):
#include "handler.h"
t::graphics::Handler::Handler(): t::misc::interface::Handler() {
}
t::graphics::Handler::~Handler() {
}
... which too is should be really trivial, but yields the error:
src\graphics\handler.cpp|5|undefined reference to `t::misc::interface::Handler::Handler()'
I'm using MinGW with Code Blocks and what ever standard settings CB uses, I've tried building the same situation with test classes and that works as intended, both in same environment and Linux with vanilla g++.
I can't see any implementation of t::misc::interface::Handler::Handler() in your code - and it is going to be called by the inheriting class's constructor, so it needs an implementation. The linker can't find it, so it complains.
Just change:
Handler();
virtual ~Handler();
in the abstract class to:
Handler() {}
virtual ~Handler() {}
and you're ready to go.
As an aside, identifiers starting with two underscores are illegal in C++ (since they are reserved for the compiler). In practice, they shouldn’t be a problem in preprocessor but it’s best to err on the safe side here: simply don’t use them.