Unreal engine Abstract class example c++ - c++

i have been looking for quite some time online for a good Abstract class (UCLASS(Abstract)) example but haven't came accross a good one yet.
Is there anyone with a good Link i can goto or Anyone who could show me a simple example, i would appreciate alot.
WeaponBase.h
UCLASS(Abstract, Blueprintable)
class FPS_API AWeaponBase : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AWeaponBase();
/** This will be used in sub classes */
UFUNCTION(BlueprintCallable, Category = "Functions")
virtual void OnFire(AFPSCharacter* Character);
}
Weapon_Assault.h
UCLASS()
class FPS_API AWeapon_Assault : public AWeaponBase
{
GENERATED_BODY()
public:
FVector spread;
AWeapon_Assault();
};
Weapon_Assault.cpp
#include "Weapon_Assault.h"
AWeapon_Assault::AWeapon_Assault()
{
AWeaponBase();
spread = FVector(0.5f, 0.0f, 100.0f);
}
// this function from abstract super class
void OnFire(AFPSCharacter* Character)
{
}
The original code is quite big so i don't want to post it here, but this is basically what it looks like, and i keep getting errors.
Also i can't even declare "OnFire" in main class and subclass at the same time?!

All class definitions must have ; after last } Like this:
UCLASS(Abstract)
class UAnimalBase : public UObject
{
GENERATED_BODY()
public:
UAnimalBase(const FObjectInitializer& ObjectInitializer);
};
You need to add a declaration of an overridden function to your Weapon_Assault.h
UCLASS()
class FPS_API AWeapon_Assault : public AWeaponBase
{
GENERATED_BODY()
public:
FVector Spread;
AWeapon_Assault();
virtual void OnFire(AFPSCharacter* Character) override; // THIS ONE
};
Note that you don't need UFUNCTION() specifier above the overridden function, only on the first declaration.
AWeapon_Assault::AWeapon_Assault() also has a mistake. You don't call constructors of parent classes in C++ they will be called automatically.
AWeapon_Assault::AWeapon_Assault()
{
// AWeaponBase(); THIS LINE IS WRONG
Spread = FVector(0.5f, 0.0f, 100.0f);
}
Create a definition for your functions in the abstract class (they can stay empty). Yes, it doesn't make sense though it does. Abstract is a specifier only inside of UnrealEngine but code still needs to be compiled with C++ standards. The absence of these definitions will cause compile errors.
We use UpperCamelCase or PascalCase in Unreal Coding Standart which is nice to have. But that one is not necessary.
So your variable should be FVector Spread; Also you probably shall wrap it with UPROPERTY() macro but that's a different topic.

Related

How can I access a private (non-static) method in C++?

Currently I am working on a project where I want to control a model train for a nice showcase.
I have multiple locomotives which all have a unique address (just think of it as a UUID). Some locomotives have a headlight, some of them have a flashing light, some have both and some of them have none.
My base class is this:
class GenericLocomotive : public Nameable, public Describable {
private:
uint16_t address;
public:
GenericLocomotive(const char* name, const char* description, uint16_t address);
void setFunction(uint8_t command, bool val);
Now I want to have a different class which provides the functionality to enable and disable the headlight:
class HasHeadLight {
public:
void activateHeadlight();
void deactivateHeadlight();
}
My goal is to have a specific class for every locomotive (with different functionality) which looks something like this:
class <SpecificLocomotive> : public GenericLocomotive, public HasHeadlight, public HasFlashlight,... {
...
}
The problem is, that I must have access to the private field 'address' of my GenericLocomotive class and I also have to call the function setFunction(...) from my HasHeadlight class.
I am quite new to C++ and just found out about the concept of friend classes and methods, but I can not quite get it to work, because even with the declaration of the method setFunction(...) as a friend, I can not just call something like
this->setFunction(HEADLIGHT_COMMAND, true);
from my HasHeadlight-class, because the function is not declared in 'this'.
How can I access the method from my other class? Is this friend thing even needed or is there a completely different way to structure my C++ program?
You have misunderstood how class inheritance works:
Inheritance establishes an is-a relationship between a parent and a child. The is-a relationship is typically stated as as a specialization relationship, i.e., child is-a parent.
There are many ways you can tackle what you want to achieve here, but this is not it. You're on the right track as far as treating the different train components as separate objects, and one way to achieve that would be to instead make each component a member of the specialized locomotive:
class HeadLight {
public:
void activateHeadlight();
void deactivateHeadlight();
}
class SpecialLocomotive : public GenericLocomotive {
HeadLight mHeadlight;
Flashlight mFlashlight;
public:
SpecialLocomotive(const char* name, const char* description, uint16_t address)
: GenericLocomotive(name, description, address) {
setFunction(HEADLIGHT_COMMAND, true);
}
void toggleLight(bool on) {
if (on) {
mHeadlight.activateHeadlight();
} else {
mHeadlight.void deactivateHeadlight();
}
}
/* so on and so forth /*
}
There's not enough details to go further with it. If you need to call setFunction from within Headlight, I would consider that a poor design choice, but there are other ways.

I cant acces functions of a base class

Currently, I am learning c++ and just for fun, I wanted to code a little chess game (without an AI of course). I use visual studio community aside and SFML 2.5 as a renderer and for graphical objects. I tried to make a model called "figure" for all figures. So I have a figure class that inherits from sfml sprite (a drawable) and a pawn class f.e. that inherits from the figure. Sf:: sprite -> figure-> pawn/queen/tower etc... but for some reason, I can't use the pawn as a sprite, for example, I can't draw it with the draw function of my windowRenderer.
But the function documentation says it requires a drawable object. I get an error message that says something like: the conversation in the base class that is not accessible is not valid. Have I done something wrong or is it not possible to use a sprite like this. Here are my constructors because I think I its most likely I made an error there. I have only coded in java so far so the separation into header and implementation file is a little foreign for me also the constructor syntax is different.
figure.h:
class figure : sf::Sprite {
public:
figure(int startPosition);
void changeImage(std::string);
void dissapear();
void loadImage(std::string);
private:
sf::Image img;
};
figure.cpp:
figure::figure(int startPosition):sf::Sprite(){
}
pawn.h:
class pawn :
public figure
{
public:
pawn(int startPosition);
~pawn();
private:
void move(bool canBeat, bool isAsStart);
};
pawn.cpp:
pawn::pawn(int startPosition):figure (startPosition)
{
}
in main.cpp:
pawn pawn1(position);
sf::RenderWindow window(sf::VideoMode(sets.windowX, sets.windowY), "frame");
window.draw(pawn1);
Try this
class figure : public sf::Sprite
Inheritence for classes is private by default.

c++ class circular reference?

I am working on a little game engine but I got stuck at something. Explanation : I have two classes, cEntity And ObjectFactory :
cEntity
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
ObjectFactory
#include "cEntity.h"
#include <vector>
class ObjectFactory
{
static std::vector<cEntity> *entityList;
static int i, j;
public:
static void addEntity(cEntity entity) {
entityList->push_back(entity);
}
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity> *ObjectFactory::entityList = new std::vector<cEntity>();
Now I am adding new cEnity to ObjectFactory in cEntity constructor but facing an error related to circular references: for using ObjectFactor::addEntity() I need to define the ObjectFactory.h in cEntity class but it creates a circular reference.
I think your code might have an underlying architectural issue given how you have described the problem.
Your ObjectFactory should be handling the cEntities, which in turn should be unaware of the "level above". From the description of the problem you are having, it implies that you're not sure what class is in charge of what job.
Your cEntitys should expose an interface (i.e. all the stuff marked "public" in a class) that other bits of code interact with. Your ObjectFactory (which is a bit badly named if doing this job, but whatever) should in turn use that interface. The cEntitys shouldn't care who is using the interface: they have one job to do, and they do it. The ObjectFactory should have one job to do that requires it to keep a list of cEntitys around. You don't edit std::string when you use it elsewhere: why is your class any different?
That being said, there's two parts to resolving circular dependencies (beyond "Don't create code that has circular dependencies in the first place" - see the first part to this answer. That's the best way to avoid this sort of problem in my opinion)
1) Include guards. Do something like this to each header (.h) file:
#ifndef CENTITY_H
#define CENTITY_H
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
#endif
What this does:
The first time your file is included, CENTITY_H is not defined. The ifndef macro is thus true, and moves to the next line (defining CENTITY_H), before it moves onto the rest of your header.
The second time (and all future times), CENTITY_H is defined, so the ifndef macro skips straight to the endif, skipping your header. Subsequently, your header code only ever ends up in your compiled program once. If you want more details, try looking up how the Linker process.
2) Forward-declaration of your classes.
If ClassA needs a member of type ClassB, and ClassB needs a member of type ClassA you have a problem: neither class knows how much memory it needs to be allocated because it's dependant on another class containing itself.
The solution is that you have a pointer to the other class. Pointers are a fixed and known size by the compiler, so we don't have a problem. We do, however, need to tell the compiler to not worry too much if it runs into a symbol (class name) that we haven't previously defined yet, so we just add class Whatever; before we start using it.
In your case, change cEntity instances to pointers, and forward-declare the class at the start. You are now able to freely use ObjectFactory in cEntity.
#include "cEntity.h"
#include <vector>
class cEntity; // Compiler knows that we'll totally define this later, if we haven't already
class ObjectFactory
{
static std::vector<cEntity*> *entityList; // vector of pointers
static int i, j;
public:
static void addEntity(cEntity* entity) {
entityList->push_back(entity);
}
// Equally valid would be:
// static void addEntity(cEntity entity) {
// entityList->push_back(&entity);}
// (in both cases, you're pushing an address onto the vector.)
// Function arguments don't matter when the class is trying to work out how big it is in memory
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity*> *ObjectFactory::entityList = new std::vector<cEntity*>();

Converting objects of base class to derived class

I asked a couple days ago some clarifications on inheritance, a concept I am still trying to understand. Here is the follow up question, since I am still facing problems.
In my project I have 2 types of objects, Hand and Face, both inheriting from the base class BodyPart. BodyPart is something like this:
class BodyPart
{
public:
typedef boost::shared_ptr<BodyPart> BodyPartPtr;
BodyPart();
virtual ~BodyPart();
private:
int commonMember1;
double commonMember2;
public:
int commonMethod1();
int CommonMethod2();
}
while Hand is something like this:
class Hand : public BodyPart
{
public:
Hand();
~Hand();
private:
int numFingers;
double otherVar;
public:
int getNumFingers();
void printInfo();
}
I also have a vector of BodyPart elements
std::vector<BodyPart::BodyPartPtr> cBodyParts;
composed of Hand or Head objects. In the previous question I was told that this approach makes sense, I just had to cast from the base class to the derived using boost static_pointer_cast
Now, the problem now is that for some of the objects in the vector I don't know whether they are Hand or Head, so at some point in my code I can have in cBodyParts some Hand elements, some Head elements as well as some BodyPart elements. After some further analysis I am able to correctly classify the latter as either Hand or Head and modify accordingly the elements in the vector, but I have no idea on how to make it. Shall I just delete the case class element and create a derived one with the same property? Shall I just avoid inheritance in case like this?
Thanks in advance for the help
EDIT: I have augmented the examples to make them clearer.
Relaying on casts is usually a sign of a bad design. Casts have their place, but this does not look to be it.
You need to ask yourself what do you want to do with the objects stored in cBodyParts. For sure, you will be doing different things with a Hand or with a Head, but you can probably abstract them somehow: this is what virtual functions do. So, in addition to what you have already written for your classes, you would just need an additional virtual function in them:
class BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}
class Head : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Head
}
// Since a Head has no joints, we don't override the CalibrateJoints() method
}
class Hand : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Hand
}
virtual void CalibrateJoints() {
// Code to calibrate the knuckles in the hand
}
}
And then you no longer need any casts. For instance:
for (BodyPart::BodyPartPtr part : cBodyParts) {
part->InitialisePart();
part->CalibrateJoints(); // This will do nothing for Heads
}
As you can see, no casts at all and everything will work fine. This scheme is extensible; if you later decide that you need additional classes inheriting from BodyPart, just write them and your old code will work correctly:
class Torso : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Torso
}
// The Torso has no joints, so no override here for CalibrateJoints()
// Add everything else the class needs
}
class Leg : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Leg
}
virtual void CalibrateJoints() {
// Code to calibrate the knee
}
// Add everything else the class needs
}
Now you don't need to change the code you wrote previously: the for loop above will work correctly with and Torso or Leg it finds with no need for an update.
The hip bone's connected to the thigh bone...
I take it you have some composite of all the body parts, maybe a Body class.
What do you want the body to do?
Render itself
Serialise
Ouput its volume, or bounding box, or some other metric
Re-orient itself in response to input
Respond to an inverse-kinematic physical model
The list could probably go on. If you know exactly what you want the Body to do you can put that function in the BodyPart base class, and have Body iterate over the composite hierarchical structure of all the connected body parts, calling render, for example.
An alternative is to use a Visitor, which is effectively a way of dynamically adding methods to a static inheritance hierarchy.
As Kerrek SB pointed out this is not feasible at all, but for the sake of answering the actual question, dynamic_cast is what you are looking for.
Use virtual functions, they will simplify a lot your problem.
Else, you can add some methods to distinguish between different types. However, do it only if you cannot do it another way, ie if you cannot do it via virtual functions.
Example 1:
// in BodyPart; to be reimplemented in derived classes
virtual bool isHand() const { return false; }
virtual bool isHead() const { return false; }
// in Hand (similar to what will be in Head)
bool isHand() const { return true; }
// How to use:
BodyPart::pointer ptr = humanBodyVector[42]; // one item from the array
if(ptr->isHand())
processHand(/*cast to hand*/)
else if(ptr->isHead())
// ...
Example 2: let the derived classes handle the cast
// in BodyPart; to be reimplemented in derived classes
virtual Hand* toHand() const { return 0; }
virtual Head* toHead() const { return 0; }
// in Hand (similar to what will be in Head)
Hand* toHand() const { return this; }

Why we need a "friend" here? (C++)

The qml viewer (for 4.8 and 5.0) is implemented like that:
In the .h(eader) we have:
class QtQuick2ApplicationViewer : public QQuickView
{
Q_OBJECT
...
private:
class QtQuick2ApplicationViewerPrivate *d;
};
Then in the .CPP file:
class QtQuick2ApplicationViewerPrivate
{
QString mainQmlFile;
friend class QtQuick2ApplicationViewer;
static QString adjustPath(const QString &path);
};
QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
: QQuickView(parent)
, d(new QtQuick2ApplicationViewerPrivate())
{
connect(engine(), SIGNAL(quit()), SLOT(close()));
setResizeMode(QQuickView::SizeRootObjectToView);
#ifdef Q_OS_ANDROID
engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
}
Why is using friend necessary here? I don't see any reason why would anybody use a friend class. Is there any real use for friend classes (except for exotics that anybody could live without)?
.h
#include
class QtQuick2ApplicationViewer : public QQuickView
{
Q_OBJECT
public:
explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
virtual ~QtQuick2ApplicationViewer();
void setMainQmlFile(const QString &file);
void addImportPath(const QString &path);
void showExpanded();
private:
class QtQuick2ApplicationViewerPrivate *d;
};
.cpp
#include "qtquick2applicationviewer.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtQml/QQmlEngine>
class QtQuick2ApplicationViewerPrivate
{
QString mainQmlFile;
friend class QtQuick2ApplicationViewer;
static QString adjustPath(const QString &path);
};
QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
{
#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
if (!QDir::isAbsolutePath(path))
return QString::fromLatin1("%1/../Resources/%2")
.arg(QCoreApplication::applicationDirPath(), path);
#elif !defined(Q_OS_ANDROID)
const QString pathInInstallDir =
QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
if (QFileInfo(pathInInstallDir).exists())
return pathInInstallDir;
#endif
#endif
return path;
}
QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
: QQuickView(parent)
, d(new QtQuick2ApplicationViewerPrivate())
{
connect(engine(), SIGNAL(quit()), SLOT(close()));
setResizeMode(QQuickView::SizeRootObjectToView);
#ifdef Q_OS_ANDROID
engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
}
QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
{
delete d;
}
void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
{
d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
setSource(QUrl::fromLocalFile(d->mainQmlFile));
}
void QtQuick2ApplicationViewer::addImportPath(const QString &path)
{
engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
}
void QtQuick2ApplicationViewer::showExpanded()
{
#if defined(Q_WS_SIMULATOR)
showFullScreen();
#else
show();
#endif
}
Friends examine friends' privates. You sure can do without access restrictions at all, but once you use it, being friendly helps in intimate situations.
class Me;
class You {
friend class Me;
private:
Home _home;
Car _car;
public:
void bar(Me my);
};
class Me {
Stuff _stuff;
public:
foo(You you) {
//If you consider me a friend
you._home.enter(); //I can enter your `private _home`
you._car.drive(); //I can drive your `private _car`.
}
};
void You::bar(Me my) {
my.stuff //this is an error because I don't consider you a friend so you can't touch my `private _stuff`.
}
Knowing you can always count on me, for sure. That's what friends are for. http://www.youtube.com/watch?v=xGbnua2kSa8
But I guess you're asking about friend classes in C++.
The whole point of "scope" is to define exactly who can see what in another class. You don't "need friends" any more than you need "protected" or "private", in the sense that you could make everything in all your classes public, and your program would successfullly compile and run. But the idea is to establish -- and document -- exactly what is the public interface of a class, and thus cannot be changed without considering the impact on other classes, and what is an internal implementation, which can be freely re-worked or re-organized without fear of impacting other classes.
So the point of a "friend" is to say: Hey, I have this class X, and this other class Y. And in general other classes don't need to know how X goes about doing it's job. But Y interacts with some low-level thing in X, so it needs to see it. Thus I make Y a friend of X. Like, I have an Investor class that has a function that (presumably among other things) has a function to calculate the total amount of a customer's investments. In general, other classes shouldn't care how I do that calculation: they just want the total. But now I have a TaxReporting class that needs to know how much of that balance is in taxable securities and how much is in non-taxable securities. Maybe I don't want to make these functions public because the information is confidential and I want to limit access for real-world privacy reasons. More often, I don't want to make it public because the calculation is tricky or subject to frequent change, and I want to keep tight control on what classes access it to limit the problems caused when things change. So I make TaxReporting a friend so it can access some functions that make the distinction, without opening these to the world.
In practice, when I was doing C++ I rarely used friends. But "rarely" is not "never". If you find yourself saying, "Oh, I have to make this public just so this one other class can see it", then maybe instead of making it public you should make a friend.
"friend" is super useful and something you want to use all the time.
Typical use cases are:
You have a class that uses subclasses where the subclass is allowed to use private functions of the class that owns the subclasses:
class ManagedObject
{
public:
void doStuff() { mMgr->updateManager(); }
private:
Manager* mMgr;
};
class Manager
{
friend ManagedObject;
public:
ManagedObject* createManagedObject();
private:
void updateManager() { }
};
So in this case you have a class that creates and deals with "managedObject". Whenever this object is manipulated it needs to update the object that created it. You want users of your class to know that they don't ever need to call "updateManager" and in fact wat to generate a compile time error if they do.
Another common case is when you have a function which acts like a class member but cannot for some reason be a class member. An example is operator<<. If you write your own io stream class, or if you want to create a serialization system that users operator<<:
class serializedObject
{
public:
friend Serializer& operator<< ( Serializer& s, const serializedObject& obj );
protected:
u32 mSecretMember;
};
Serializer& operator<<( Serializer& s, serializedObject& obj )
{
serializer << obj.mSecretMember;
return s;
}
In this case the serialization function cannot be a member of serializedObject, but needs to look at the internals of serializedObject to serialize it. You will see similar patterns of you create other operators ( like addition ) where the RHS of the operator is not the same class as the LHS
In Qt, there is something called a 'guarantee of binary compatibility', which means that your app can run against Qt4.8, 4.8.1, and 4.8.2 and so forth without recompiling.
In order to achieve this the vtable for objects cannot change. So, Qt classes are written using the "PIMPL" (pointer to implementation) idiom.
The "Private" class is the PRIVATE implementation of the public class - it is an implementation detail of QtQuick2ApplicationViewer. No one in the whole world knows about the private class except the public class. These two classes are deeply intertwined by design. In fact, they are really different aspects of a single object that has been partitioned c++ wise in order to achieve the binary compatibility guarantee.
It is reasonable in this context that the private class can access the public class.
2) In this context quit is not QApplication::quit(), that is slot of cause, but some internal signal of engine().