declare function of class inline [duplicate] - c++

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.

Related

Is there a way to hide the private members of a class, to the clients of that class?

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.

MSVC requires to import DLL for an inline-able compiler-generated constructor

I got a weird C++ question and have no idea how to resolve it.
I have a public header:
// a.h
#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif
struct A_API IWorker
{
virtual bool foo() { return false; }
};
I built a.DLL with -DA_EXPORTS.
But my test.exe just needs a mocked IWorker.
// test.cpp
#include "a.h"
class CMockWorker : public IWorker
{
public:
bool foo() override { return true; }
};
I built test.exe, and found it depends on a.DLL because of external symbol public: __cdecl IWorker::IWorker(void) __ptr64
I know that IWorker has a compiler-generated constructor because of the vtbl, but could it be inline so we can get rid of a.DLL?
Thanks!
As #hans-passant mentioned, yes, once I removed the definition of virtual methods, problem resolved.
// a.h
struct IWorker
{
virtual bool foo() = 0;
};
But in existing project, some so-called interface class has similar dummy body and hard to refactor them.
So I really want to find the ideal solution to force-inline the c'tor, if has. Maybe not today, hope it could be impl-ed in the future.

Base class undefined

I know it is one of the constant ask question
so i get this error
'WorldObject': [Base class undefined (translated from german)]
Here is the code which produce this error:
ProjectilObject.h:
#pragma once
#ifndef _PROJECTILOBJECT_H_
#define _PROJECTILOBJECT_H_
#include "GameObjects.h"
class ProjectilObject: public WorldObject
{
public:
ProjectilObject(IGameObject* parent,int projectiltype);
void deleteyourself();
protected:
virtual void VProcEvent( long hashvalue, std::stringstream &stream);
virtual void VInit();
virtual void VInitfromStream( std::stringstream &stream );
virtual void VonUpdate();
virtual void VonRender();
private:
vec3 vel;
float lifetime;
float lifetimeend;
vec3 target;
int m_projectiltype;
};
#endif
Here is the code file from the WorldObject class:
GameObjects.h:
#pragma once
#ifndef _GAMEONJECTCODE_H_
#define _GAMEONJECTCODE_H_
#include "IGameObject.h"
#include "Sprite.h"
#include "GamePath.h"
#include "HashedString/String.h"
#include "IAttribute.h"
#include "CharacterObjects.h"
#include "ProjectilObject.h"
[...]
class WorldObject: public IGameObject, public MRenderAble
{
public:
WorldObject(IGameObject* parent);
virtual bool IsDestroyAble();
virtual bool IsMageAble();
virtual bool IsRenderAble();
protected:
virtual void VProcEvent( long hashvalue, std::stringstream &stream);
virtual void VonUpdate();
virtual void VonRender();
virtual void VInit() =0;
virtual void VInitfromStream( std::stringstream &stream ) =0;
virtual void VSerialize( std::stringstream &stream );
vec3 poscam;
};
[...]
#endif
There are some other Classes in this file but they shouldn't interrupt, I think.
Maybe there is a tiny error I didn't saw but I don't understand why this error is produced. When you need more of the code feel free to ask because i think it would only disturb.
If you have any source file that includes GameObjects.h before ProjectilObject.h or does not include ProjectilObject.h directly, then the compiler will first find the declaration of ProjectilObject through the include in GameObjects.h before knowing what WorldObject is. That is because GameObjects.h first includes ProjectilObject.h and then declares WorldObject. In that case the include of GameObjects.h present in ProjectilObject.h won't work because _GAMEONJECTCODE_H_ will be already defined.
To avoid this, either be sure to include ProjectilObject.h instead of GameObjects.h in your source file, or use forward declarations.
It's hard to answer this question without looking at the whole code. Even a misplaced brace could count. Check your namespaces - are you sure the WorldObject is in the same namespace?
I suggest you use the #pragma message by placing it near the WorldObject definition and checking the compiler output:
#pragma message ("World object is defined")
If it does not show up, move the pragma to the parent .h file and check the compiler output again. With this you can easily locate the error.
class WorldObject;
class ProjectilObject: public WorldObject
You are forward declaring WorldObject, but to inherit from a class you need the definition, so you have to include the header of WorldObject.
In my case: i delete derived class include from base class header file.
for example:
file 1 :
#include "B.h"
-> A()
file 2:
-> B() : A()
solution : delete #include "B.h" from file1

Accessing Static Method and Static bool in other class

I have a base interface class:
class A
{
public:
ITask(){}
virtual bool Start()=0;
virtual void Update()=0;
virtual void Stop()=0;
};
I now have 2 other classes, that inherit from this
#include "A.h"
#include "C.h"
class B: public A
{
public:
bool Start(){}
void Update()
{
c.Start();
}
void Stop(){}
static bool m_run;
static void SetRun(bool run)
{
m_run = run;
}
private:
C c;
};
lastly I have a 3rd class:
#include "A.h"
#include "B.h"
class C : public A
{
public:
bool Start()
{
B::SetRun(false); // cant do this
B::m_run = false; // or this
}
void Update()
{
}
void Stop()
{
}
}
I have shaved down some of the code, for simplicity.
I dont understand why I cant access the static var in B. Do I need to make it a pointer or a ref?
I get 2 errors:
error C2653: 'B' : is not a class or namespace name
error C3861: 'm_run': identifier not found
Although you don't show it, I'm assuming that B.h includes C.h; otherwise the line C c; won't compile. This causes a circular dependency in the header files: B.h must be included before C.h, which must be included before B.h, which is impossible.
The easiest solution is to move the body of C::Start out of the definition of C, so that C.h does not need to include B.h. The function definition can go into a source file, or a separate header if you want to keep it inline.
Alternatively, you could modify B to contain a std::unique_ptr<C> rather than an instance of C, and implement a constructor (in a source file, or a separate header) that initialises it with new C. Then B.h only needs to forward declare class C; rather than including C.h.
A better solution, if possible, would be to rethink the relationships between the classes so that there isn't a circular dependency.
(UPDATE: while I was writing this answer, the question changed to show that B.h does indeed include C.h as I guessed.)
There is nothing wrong with your example code (after the edits), the problem must be somewhere else, like a failed include.

C++: Avoid .cpp files with only an empty (de)constructor

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.