C++ - How to call creator class/object - c++

I need to call properties and functions of an object from a different class.
The idea is passing 'this' as a parameter to the other class constructor. E.g.:
instance = ClassName(this);
And then do:
ParentClass parentInstance;
ClassName::ClassName(MainApp _instance){
parentInstance = _instance;
}
However, my compiler says that ParentClass does not name a type. Ideas?
Also, should I use a pointer to save memory? How?
Thanks in advance.
UPDATE:
Ok, sorry for the delay. Here it goes the actual code. First, a simple class.
Game class:
Header file
#ifndef _GAME
#define _GAME
#include "ofMain.h"
class Game{
public:
Game();
~Game();
void hi();
};
#endif
cpp file:
#include "Game.h"
Game::Game(){}
Game::~Game(){}
void Game::hi(){
cout << "hi, I'm game! " << endl;
}
Then, from MainApp I create the object:
- Relevant code on header file:
#ifndef _MAIN_APP
#define _MAIN_APP
#include "ofMain.h"
#include "Game.h"
class MainApp : public ofSimpleApp{
public:
Game game;
};
#endif
Relevant code on the cpp file:
game = Game();
game.hi();
This obviously works as I'm only creating a bloody object. However, problem comes with composition.
I could pass the main app as argument in the constructor, I could pass it via game.setParent(this);... problem is, I can't even define the variable to store the reference to the app.
E.g.: (making it easy/inefficient without pointers or anything)
Game.h:
#define _GAME
#ifndef _GAME
#include "ofMain.h"
#include "MainApp.h"
class Game{
MainApp app;
public:
Game();
~Game();
void hi();
};
#endif
This returns a "does not name a type" error and declaring class MainApp returns an "incomplete type" error
I'm sure I'm doing something dumb.
UPDATE 2:
The problem with that method is that I can't call a function of the pointed object now.
This is Game.h:
#ifndef _GAME
#define _GAME
#include "ofMain.h"
class MainApp;
class Game{
public:
Game();
Game(MainApp* _app);
~Game();
void hi();
MainApp* app;
};
#endif
As you see, app (of the type MainApp) is passed as a parameter. That's fine, MainApp exists as it's the forward declaration. However, when I try to call any of app's functions I can't (compiler error saying Request for member appHi in .... which is non-class type 'MainApp'.
MainApp is NOT included in Game.h but Game.h IS included in MainApp.h.
Ideas?

The problem is you have a circular reference - Game includes MainApp, and MainApp includes game. You need a 'forward declaration', as per the example by DeadMG.
See here.

It's called composition and is a common pattern. It's highly efficient in both semantics and in terms of runtime speed/memory footprint.
Your code example is a little too much pseudocode for me to read it correctly. Let me show you how it's done.
class X;
class Y {
...
void DoSomething(X* x, ... args);
};
class X {
Y y;
void DoSomething() {
y.DoSomething(this, args);
}
};

I think there may be two issues here:
1) You need to declare the ParentClass (i.g. #include its .hpp-file) before using it
2) The assignment "parentInstance = _instance" will invoke the assignment operator, which i'm guessing is not what you want. let "parentInstance" be a pointer instead.

Note the section on "#include."
http://www.cplusplus.com/doc/tutorial/program_structure/
After the "Intro to the C++ Language" section look for the verbiage about #include.
http://www.cprogramming.com/tutorial/lesson1.html
Namespaces:
http://www.tenouk.com/Module23.html
HTH

That's not how things work in C++. Unlike javascript, you cannot inject methods or fields into existing objects at runtime.

Madsen is on the right track here, but we need more code; What is the class heirarchy of ParentClass, ClassName and SaleraApp. Which classes are base and/or dervied?
When you write: parentInstance = _instance; the compiler will try to generate a default copy constructor if one is not defined. Your problem might be that you are trying to create a dervied class object from a base class pointer.
Also, "this" is a pointer.

If all you need to do is use functions and data members of another class, read up on the friend keyword. It will allow access to class members from other classes.
UPDATE: Alternatively, store a pointer or reference to the object you need access to, and make getters for data members and make the functions public... but I get the feeling this is not what you're after...

Related

c++ how to know where to forward declare in state pattern

This question comes from this question.
Im trying to implement the state pattern with a shared_ptr to the container(game).
However I have a problem with circular inclusion and need to forward declare.
My code:
Game.h
#pragma once
#include <memory>
#include "BaseState.h"
class Game : public std::enable_shared_from_this<Game>
{
private:
std::shared_ptr<BaseState> currentState;
public:
Game();
void switchState(std::shared_ptr<BaseState> nextState);
void doSomething(char);
void runState();
};
cpp
#include "stdafx.h"
#include <iostream>
#include "Game.h"
#include "SomeState.h"
Game::Game()
{
currentState = std::make_shared<SomeState>();
}
void Game::switchState(std::shared_ptr<BaseState> nextState)
{
currentState = nextState;
}
void Game::doSomething(char c)
{
std::cout << "Game : " << c;
}
void Game::runState()
{
currentState->handleCommand(shared_from_this());
}
BaseState.h
#pragma once
#include <memory>
#include "Game.h"
class BaseState
{
public:
virtual void handleCommand(std::shared_ptr<Game>) = 0;
};
SomeState.h
#pragma once
#include "BaseState.h"
class SomeState :
public BaseState
{
public:
// Inherited via BaseState
virtual void handleCommand(std::shared_ptr<Game>) override;
};
cpp
#include "stdafx.h"
#include "SomeState.h"
void SomeState::handleCommand(std::shared_ptr<Game> game)
{
game->doSomething('S');
}
I read other questions about forward declaring but still don't get it.
What I tried;
forward declare BaseState in Game, the code compiles but throws an error.
Unhandled exception at 0x73E9DAE8 in ConsoleApplication1.exe:
Microsoft C++ exception: std::bad_weak_ptr at memory location
0x00BBF5D4.
Forward declare Game in BaseState. Dosnt compile gives use of undefined type error, also
'doSomething': is not a member of
'std::shared_ptr'
which is logic because at compile time game has not a doSomething function because forward declared like;
class Game;
How do I decide where to forward declare another class, are there any logical steps or should I just pick one and fix the problems that choise creates?
You don't need to #include <Game.h> in BaseState.h, you can simply forward-declare it
class Game;
This works because the BaseState declaration doesn't need to know the contents of Game. So what you tried first is OK. The same applies to #include <BaseState.h> in Game.h. Replace that with a forward-declaration of BaseState.
The std::bad_weak_ptr exception was due to something else. Specifically, you're probably missing the little detail about shared_from_this, which says
It is permitted to call shared_from_this only on a previously shared
object, i.e. on an object managed by std::shared_ptr. Otherwise the
behavior is undefined
and
(from C++17) std::bad_weak_ptr is thrown (by the
shared_ptr constructor from a default-constructed weak_this)
You can usually solve this by instantiating your object into a shared_ptr:
int main() {
auto myGame = std::make_shared<Game>();
. . .
myGame->runState();
. . .
}
EDIT
Keep in mind though, that shared_ptr has a certain cost associated with using it. In general, if you know the pointed-to object always outlives the function call where it is used, as might be the case with your BaseState::handleCommand, then it may be faster (and still safe) to just pass it by reference.

How to access function from another class?

Stupid question probably, but I couldn't find the answer (even here).
I have split all my classes in separate files (cpp+h). I have methods like getValue() and setValue(). I have class called Player (this is basically the database with whole number of variables). I created an object called player (Player *player = new Player;). Now I need to access THIS object from any other class (that separated in another file). The problem is that I cannot even access getValue() / setValue() methods.
What I need is something like in Delphi From1.player.item[0]=3 access from form 2, where the player is recorded.
UPD:
Here's my code:
Player.cpp
#include "player.h"
#include "gameform.h"
Player::Player()
{
}
void Player::check(){
//I should be able to check if player dead or not from my Battle class
}
player.h
#ifndef PLAYER_H
#define PLAYER_H
class Player
{
public:
Player();
void check();
};
#endif // PLAYER_H
Battle.cpp
#include "battle.h"
#include "player.h"
#include "game.h"
Battle::Battle()
{
}
void Battle::hit(){
//if I hit I should check am I dead yet
player.check();
}
That's how Player declared in Game class (now):
Player *player = new Player;
Outside of any functions, just in class.
Where player is object, created in Game class. All things are public.
*I've tried even creating object in main.cpp (both in and out of main() function), and nothing working, weird =/
This is github "temp" branch, compiling and working. But how to access player? :)
https://github.com/ewancoder/game/tree/temp
UPD: Another stupid question: If I want that in my class 1 function is responsible for opening file and another - for editing and closing file, how can I do that if one cannot read vars from another?
I'm not sure what you want, but if you have a class like this:
a.hpp
Class A {
public:
void foo();
};
a.cpp
#include "a.hpp"
void A::foo() {}
You can use it like this:
b.hpp
#include "a.hpp"
class B {
public:
void stuff(A& a);
};
b.cpp
#include "b.hpp"
void B::stuff(A& a) { a.stuff(); }
You need to give the other object the reference of the first. Either direct in the constructor or later via a method.
Or alternativly you could store player in a global variable and access it via the global variable.
The problem is that the methods are bound to the specific instance of the object - and so you need that instance to call them
You need to add parenthesis to the end of the statement and use the -> operator, not the . operator: player->check()
This is because it is a pointer to an object Player *player and not an object itself Player player
Your question is a little hard to follow, and some of the answers reflect that. However, in my view what you are running into is actually a critically important part of your system design. There are many strategies, and many considerations, but basically it's up to you to design the paths by which objects can access the contents of other objects in your running program.
Some common techniques include
Global variables
extern Player *PlayerOne;
PlayerOne->item[0]=3;
Static variables (or collections) in the class.
class Player {
public:
Player* Players;
}
Player::Players[0]->item[0]=3;
Member variables.
Board.Add(new Player(Board));
Board.m_player->item[0]=3;
The variations are endless. You'll need to be more specific if you want specific code.

Pointer initialization in constructors

I am developing a client-database using MFC and lately I was trying to create a class in order to perform DAO operations (instead of implementing these operations directly at the CDocument class). I named this class as CModel, and CDocument contains it. In order to perform SQL operations using the CModel class, I must have access to the m_session variable - which represents a database access session - and it can be found in the RecordSet class - which represent one table in a database of mine. Here is a piece of code to better illustrate the situation:
#pragma once
#include "MFCApplicationSet.h"
class CModel
{
public:
CModel(CMFCApplicationSet ApplicationSet);
~CModel();
CMFCApplicationSet * pModelSet;
}
// Model.cpp : implementation file
//
#include "stdafx.h"
#include "MFCApplication.h"
#include "Model.h"
#include "SQLQuery.h"
#include "MFCApplicationSet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CModel::CModel(CMFCApplicationSet ApplicationSet)
{
pModelSet = &ApplicationSet //not sure if it is right
}
CModel::~CModel()
{
}
// MFCApplicationDoc.h : interface of the CMFCApplicationDoc class
#pragma once
#include "MFCApplicationSet.h"
#include "Model.h"
class CMFCApplicationDoc : public CDocument
{
protected: // create from serialization only
CMFCApplicationDoc();
DECLARE_DYNCREATE(CMFCApplicationDoc)
// Attributes
public:
CMFCApplicationSet m_MFCApplicationSet;
CModel Model;
}
// MFCApplicationDoc.cpp : implementation of the CMFCApplicationDoc class
//
#include "stdafx.h"
#ifndef SHARED_HANDLERS
#include "MFCApplication.h"
#endif
#include "MFCApplicationSet.h"
#include "MFCApplicationDoc.h"
#include "Model.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CMFCApplicationDoc, CDocument)
BEGIN_MESSAGE_MAP(CMFCApplicationDoc, CDocument)
END_MESSAGE_MAP()
// CMFCApplicationDoc construction/destruction
CMFCApplicationDoc::CMFCApplicationDoc()
{
//problem in implementing a instruction to call the Model object constructor
}
CMFCApplicationDoc::~CMFCApplicationDoc()
{
}
I've used the debugger to analyse my code flow and I noticed that, from the CMFCApplicationDoc constructor (CDocument), the constructor from each variable declared in the CMFCApplicationDoc.h is initialized. Here's my problem: I've tried to create a CModel constructor in order to the pModelSet pointer automatically reference the variable m_MFCApplicationSet (check the constructor arguments) declared in the Doc class, but I am experiencing some trouble in giving this instruction inside the construction of the Doc class. Is there a specific or maybe an alternative way to do this? (sorry if this task is kind of elementary, but I am still very newbie in C++)
Your constructor:
CModel(CMFCApplicationSet ApplicationSet);
takes object of type CMFCApplicationSet by value, meaning that the copy of passed object is created and this copy is then used within its body. When you do the following:
pModelSet = &ApplicationSet;
you are actually storing the addres of temporary object, which is destructed when execution goes out of the scope of the constructor. If you try to dereference this pointer afterwards, it will produce undefined behavior.
Some might suggest you to pass a pointer, but if you look at your CModel class closely, you will see that it has only one constructor and it takes the PessoaSet object, i.e. the instance of CModel requires the existance of some object of type PessoaSet, i.e. you should keep a reference, not a pointer:
class CModel
{
public:
CModel(CMFCApplicationSet& ApplicationSet) : modelSet(ApplicationSet) { }
CMFCApplicationSet& modelSet;
}
and in the other class that contains instance of CModel:
class CMFCApplicationDoc
{
public:
CMFCApplicationDoc() :
Model(m_MFCApplicationSet) { }
CMFCApplicationSet m_MFCApplicationSet;
CModel Model;
}
just note that the order, in which members of CMFCApplicationDoc are declared actually matters here, since you want m_MFCApplicationSet to be initialized earlier than Model and the standards (12.6.2 §5) says: "nonstatic data members shall be initialized in the order they were declared in the class definition".

C++ cannot establish handle reference to 'parent' object -- circular includes or undefined type errors

I'm looking to have a hierarchical class structure in which a level of controller 'parent' classes are responsible for creating/directing a number of 'child' classes. The parent class should be able to reference each child it creates directly, and each child should be able to reference its parent (and, assuming this child is not also a parent of more classes, only its parent) directly. This allows for the referencing of siblings through the parent. I've found this paradigm to be useful in JIT compilation languages like Java and C#, but C++ presents a unique problem...
My first attempt to implement this paradigm was as follows:
Parent Class TreeRoot.h
#ifndef __CCPP_SCENE_H__
#define __CCPP_SCENE_H__
#include "ChildA.h"
#include "ChildB.h"
class TreeRoot :
{
private:
ChildA* a;
ChildB* b;
public:
//member getters
ChildA* getA();
ChildB* getB();
};
#endif // __CCPP_SCENE_H__
Child class ChildA.h
#ifndef CHILDA_H_
#define CHILDA_H_
#include "TreeRoot.h"
class ChildA
{
private:
TreeRoot* rootScene;
public:
ChildA(TreeRoot*);
~ChildA(void);
TreeRoot* getRootScene();
void setRootScene(TreeRoot*);
};
#endif /*CHILDA_H_*/
Child class ChildB.h
#ifndef CHILDB_H_
#define CHILDB_H_
#include "TreeRoot.h"
class ChildB
{
private:
TreeRoot* rootScene;
public:
ChildB(TreeRoot*);
~ChildB(void);
TreeRoot* getRootScene();
void setRootScene(TreeRoot*);
};
#endif /*CHILDB_H_*/
Now of course that wouldn't compile because of the circular include (TreeRoot.h includes ChildA.h and ChildB.h, which both include TreeRoot.h etc) So I tried using forward declaration instead:
Parent Class TreeRoot.h
#ifndef __CCPP_SCENE_H__
#define __CCPP_SCENE_H__
#include "ChildA.h"
#include "ChildB.h"
class TreeRoot :
{
private:
ChildA* a;
ChildB* b;
public:
//member getters
ChildA* getA();
ChildB* getB();
};
#endif // __CCPP_SCENE_H__
Child class ChildA.h
#ifndef CHILDA_H_
#define CHILDA_H_
//#include "TreeRoot.h" //can't use; circular include!
class TreeRoot;
class ChildA
{
private:
TreeRoot* rootScene;
public:
ChildA(TreeRoot*);
~ChildA(void);
TreeRoot* getRootScene();
void setRootScene(TreeRoot*);
};
#endif /*CHILDA_H_*/
Child class ChildB.h
#ifndef CHILDB_H_
#define CHILDB_H_
//#include "TreeRoot.h" //can't use; circular include!
class TreeRoot;
class ChildB
{
private:
TreeRoot* rootScene;
public:
ChildB(TreeRoot*);
~ChildB(void);
TreeRoot* getRootScene();
void setRootScene(TreeRoot*);
};
#endif /*CHILDB_H_*/
that implementation almost works in that I can successfully broadcast messages to the child objects and perform callbacks from the child objects to the parent class as follows:
TreeRoot.cpp
...
a->someChildMethod();
a->getRootScene()->someParentMethod();
However when I try the following:
ChildA.cpp
...
rootScene->someParentMethod(); //ERROR C2027: use of undefined type TreeRoot
I get an undefined type error. This makes sense since using forward declaration as above doesn't inform the compiler of what TreeRoot actually is. The question then is how can I enable calls from the child objects like the rootScene->someParentMethod() call above? Perhaps some use of generic types via templates would make the compiler happy and provide the functionality I'm looking for?
thanks,
CCJ
Use a forward declaration in all your .h files. You can do this since you're only storing pointers as class members so you don't need the full class declaration.
Then, in all your corresponding .cpp files, #include the header files for the classes you need.
So, in TreeRoot.h you forward declare ChildA and ChildB. In TreeRoot.cpp, you #include ChildA.h and ChildB.h.
Rinse and repeat for your 2 other classes.
Take note that this will solve your current problem, but this design seems flaky at best.
You could try including the 'TreeRoot.h' in the ChildA and ChildB files. I would also suggest using Polymorphism and create a parent class, which A and B inherit from, for shared behaviour.
This doesn't involve fiddling with the header files, but my suggestion: Either make all your nodes the same class (enables more flexibility [what if you decide you want to make a tree into a subtree of another tree? you'd have to change the class of the root node from the first tree into the child class], and, at least in my mind, makes more sense/seems more elegant/would lessen the amount of and/or simplify the code you'd have to write), or use a superclass for both parent and child node classes (as ATaylor suggests), though I feel that would only be a better solution if your parent and child nodes have a lot of differing functionality beyond that which they would require to form the tree structure.
In ChildA.cpp file you have to include the parent header as
#include "TreeRoot.h"

C++. Child inherits from Parent and is included as Parent attribute

I have a very simple Child-Parent relationship, where OlderSon inherits from Parent and a Parent has a pointer to his OlderSon, such as:
#ifndef PARENT_HXX
#define PARENT_HXX
#include <iostream>
#include <string>
//#include "OlderSon.hxx"
class OlderSon;
class Parent
{
private :
OlderSon* _os;
public :
int _age;
std::string _name;
Parent(){
_name="parent name";
_age=60;
//OlderSon* _os=new OlderSon();
}
};
#endif //PARENT_HXX
And son:
#ifndef OLDERSON_HXX
#define OLDERSON_HXX
#include <iostream>
#include <string>
#include "Parent.hxx"
class OlderSon: public Parent
{
public:
OlderSon(){
_age=25;
_name="Olderson name";
}
};
#endif //OLDERSON_HXX
However whenever I try to uncomment the line where the pointer is initialized OlderSon* _os=new OlderSon(); I get an error message:
Parent.hxx: In constructor ‘Parent::Parent()’:
Parent.hxx:25:31: error: invalid use of incomplete type ‘struct OlderSon’
Parent.hxx:8:7: error: forward declaration of ‘struct OlderSon’
I tried in different ways, namely including both .hxx or by forward declaration, but nothing seems to help. I guess it's not a very complex issue, but it is starting to be frustrating.
Any ideas?
Thanks in advance!
You are attempting the impossible. You can fix the bug by moving the implementation of Parent:Parent to the implementation file, but your code would still be disastrous.
Constructing a Parent would require constructing an OlderSon and constructing an OlderSon would require constructing a Parent too (since an OlderSon is a Parent). You would have infinite recursion.
You can't both have Parent's constructor call OlderSon's and vice-versa!
why not you define child pointer to as Parent * like;
class Parent
{
private :
Parent* _os;
.
.
.
}
Since base class of child is parent.
The Parent() constructor uses a constructor for OlderSon().
But it doesn't know OlderSon, because you only forward-declarated it.
(which means: I'm gonna use a class called OlderSon, but all you (Parent.hxx) have to know is its name, because in this Header-file I'm only using a pointer to it.)
Try to implement the Parent() constructor in a cxx file where you include OlderSon.hxx
EDIT:
I oversaw the fact that OlderSon inherits from Parent... which results in an infinite recursion, which is probably not what you want.