I'm working on a VTK program and have found a class (specifically this one: Image Region) which i need to incorporate into my code. To do so I have made a separate ImageRegion.h and ImageRegion.cpp files so they can be easily included in the project. My Problem here is the
static vtkBorderCallback *New()
function which i do not know how to implement in the .cpp file or, to be quite honest, what purpose it serves at all. What does it do? Is it even necessary to have it?
When compiling I get the error:
/home/Desktop/test/src/ImageRegion.cpp:7:10: error: ‘vtkBorderCallback::vtkBorderCallback’ names the constructor, not the type
My .h file:
//ImageRegion.h
#pragma once
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkAssemblyNode.h>
#include <vtkAssemblyPath.h>
#include <vtkBorderRepresentation.h>
#include <vtkCommand.h>
#include <vtkCoordinate.h>
#include <vtkImageMapper3D.h>
#include <vtkImageActor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkPolyData.h>
#include <vtkPropPicker.h>
#include <vtkProperty2D.h>
#include <vtkBorderWidget.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
class vtkBorderCallback : public vtkCommand
{
public:
vtkBorderCallback();
static vtkBorderCallback *New();
virtual void Execute(vtkObject *caller, unsigned long, void*);
void SetRenderer(vtkSmartPointer<vtkRenderer> ren);
void SetImageActor(vtkSmartPointer<vtkImageActor> im);
double coords[6];
private:
vtkSmartPointer<vtkRenderer> Renderer;
vtkSmartPointer<vtkImageActor> ImageActor;
};
And my .cpp file:
//ImageRegion.cpp
#include "ImageRegion.h"
vtkBorderCallback::vtkBorderCallback(){}
static vtkBorderCallback::vtkBorderCallback* New()
{
return new vtkBorderCallback;
}
void vtkBorderCallback::Execute(vtkObject *caller, unsigned long, void*)
{
//Do stuff, from original VTK example code
}
void vtkBorderCallback::SetRenderer(vtkSmartPointer<vtkRenderer> ren) {this->Renderer = ren;}
void vtkBorderCallback::SetImageActor(vtkSmartPointer<vtkImageActor> im) {this->ImageActor = im;}
Any help is much appreciated.
This
static vtkBorderCallback *New();
is a static member function called New, taking no arguments, and returning a pointer to vtkBorderCallback.
In the implementation, you should omit the static. You also need to place the function in the scope of its class:
vtkBorderCallBack* vtkBorderCallback::New()
{// ^^^^^^^^^^^^^^^^^^^
return new vtkBorderCallback; // danger! Caller needs to delete this eventually
}
In VTK nearly all of the classes derive from vtkObjectBase. They should use New() and Delete() to create and delete the objects (the constructor and destructor are protected). These methods include referencing counting to make sure that they get properly shared among other vtkObjects that may use them. There is a VTK macro (vtkStandardNewMacro) that takes care of the implementation of New() and the base class implements Delete(). So for VTK, the best way to implement the static New() method is to use that macro. For your class called vtkBorderCallBack it would look like:
vtkStandardNewMacro(vtkBorderCallBack);
This should go in your .cpp file.
To solve the error, put vtkBorderCallBack:: before New():
vtkBorderCallBack* vtkBorderCallBack::New()
~~~~~~~~~~~~~~~~~~~
{
...
}
He should not omit static since New() is meant as constructor. In this scenario I would rather expect the real constructor to be private. The implementation
static vtkBorderCallback::vtkBorderCallBack* New()
{
return new vtkBorderCallback;
}
is syntactically wrong. It has so be
vtkBorderCallBack* vtkBorderCallback::New()
{
return new vtkBorderCallback;
}
Finally the whole approach is strange. New() is not really required here, and possibly leads to a memory leak. To establish a class-specific memory management overload operators new and delete on a per-class basis. Alternatively, to prevent leaks, do not return a raw pointer; return std::auto_ptr (deprecated) or std::unique_ptr:
std::unique_ptr<vtkBorderCallBack> vtkBorderCallback::New()
{
return std::unique_ptr<vtkBorderCallBack>(new vtkBorderCallback); // uses move c'tor
}
However, std::unique_ptrs are movable but not copyable. But that's the point when leaks have to be prevented. When the pointer returned by New() is spreaded all over the code better use a std::shared_ptr.
If you have only a C++03 compiler I recommend Herb Sutter's Using auto_ptr Effectively.
Related
I'm fairly new to C++, this is also my first post on here. I'm trying to use C++ in an embedded systems project so I can take the OOP approach. I'm using the AVR crosspack toolchain (AVR G++ compiler)
My problem is this:
From what i've read, the heap should not be used for dynamic memory allocation in embedded systems. In any case, there is no implementation for "new" in AVR G++ anyway. I'm using composition, starting with a USART driver (lets call it a service), and a logger (singleton pattern, and also a service).
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, however when I try to compose the objects needed in this way I get the following error:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
My sense is that my syntax for passing in an object as a constructor parameter is wrong, but I'm not sure what it should be as all the examples i can find use the "new" keyword in the constructor definition to create the object on the free store. Can anyone help?
The Code:
In "usart.h":
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
In "logger.h":
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
In "logger.cpp"
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
In "main.cpp":
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
It depends. I'm currently in an embedded project with maximum safety-related requirements, and we use new, but not delete. So we have a heap, but don't allocate "dynamically", because all allocated objects are kept during the runtime.
In any case, there is no implementation for "new" in AVR G++ anyway.
Is this true? I never checked... It might be necessary to provide a heap before being able to use new.
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
This is a good idea. ;-) It helps unit-testing.
For your syntactical and design problems: This is how I would write your sources.
"usart.h":
All methods are non-static to have access to member variables.
The const attribute on a return type is doing nothing. Did you mean to declare the method constant? Then const belongs after the parameter list. However, this attribute might be wrong if such a method changes any member variable.
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
Just give and store a reference to the USART to avoid a copy.
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
The member variable _usart is directly initialized in the constructor, before any statement is executed.
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
Provide the USART object on the stack, as the logger.
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
The singleton design pattern is deprecated since it was invented, because it is so hard to test. Simply use just one object or a limiting object factory.
I am trying to make functions repository. I have created four files:
Function.hpp, Function.cpp, FunctionsRepository.hpp, FunctionsRepository.cpp
I want to keep pointers to functions in vector of pointers.
//FunctionsRepository.hpp
#ifndef FUNCTIONSREPOSITORY_HPP
#define FUNCTIONSREPOSITORY_HPP
#include <vector>
using namespace std;
class FunctionsRepository {
private:
static vector<double *> pointerToFunctions;
public:
static void addFunction(double * wsk);
};
#endif
//FunctionRepository.cpp
#include "FunctionsRepository.hpp"
void FunctionsRepository::addFunction(double * wsk) {
pointerToFunctions.push_back(wsk);
}
//Functions.hpp
#ifndef FUNCTIONS_HPP
#define FUNCTOINS_HPP
#include "FunctionsRepository.hpp"
int constFunction(int numberOfVehicles);
void linearFunction();
void stepFunction();
#endif
//Funcctions.cpp
#include "Functions.hpp"
double constFunction(double numberOfVehicles){
return numberOfVehicles/2;
}
double (*funcConstant)(double) = constFunction;
//ERROR HERE
FunctionsRepository::addFunction(funcConstant);
I want to add new functions to program as easily as its possible and use it leater in other parts of program.
But I dont get it. Why i am getting this error. The addFunction() method is static, that means I can use it in other classes or parts of program. Vector is static to make sure that is the only one copy for whole program.
Use function wrapper. std::function can stores callable objects. So, your code will contain something like this:
class FunctionsRepository {
private:
// void() - function prototype
static std::vector<std::function<void()>> pointerToFunctions;
public:
static void addFunction(std::function<void()> wsk)
{
pointerToFunctions.push_back(wsk);
}
};
for more information consult official documentation: http://en.cppreference.com/w/cpp/utility/functional/function
I solved It. I received an error because I was calling the FunctionsRepository::addFunction(funcConstant); expression out of any scope. I just created new function to execute this command and thats all.
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.
I keep having problems with this. If I define an object in main.cc, how do I access that object from another .cc file?
main.cc:
#include "Class.h"
#include "header.h"
int main()
{
Class object;
return 0;
}
file.cc:
#include "header.h"
void function()
{
object.method(parameter);
}
What would I have to put in header.h to get this working? Any help would be appreciated.
how do I access that object from another .cc file?
What would I have to put in header.h to get this working?
The simple answer to is to "pass the object by reference".
An object created in main() lasts for the entire program. This is typical in embedded systems ... I have no issues with this aspect.
I would, however, put the long lasting object in dynamic memory (because the stack is more limited).
main.cc:
#include "Class.h"
#include "header.h"
int main()
{
Class* object = new Class;
function(*object); // <--- pass the object by reference
return 0;
}
file.cc:
#include "Class.h"
#include "header.h"
void function(Class& object) // <-- how to specify reference
{
object.method(parameter); // <-- you did not identify parameter
}
header.h
class Class; // <--- poor name choice
void function (Class& object); // <--- another poor name choice
// note that the compiler needs to know only that Class is a
// user defined type -- the compiler knows how big a reference
// or ptr to the class is, so you need not provide more Class info
// for this file
Of course, you still need to write Class.h and define Class
Update - You have marked this post as C++.
So, please consider the following (which sidesteps the pass by reference dilemma):
main.cc:
#include "Class.h"
#include "header.h"
int main()
{
Class* object = new Class;
//
// I recommend you do not pass instance to function.
//
// Instead, the C++ way is to invoke an instance method:
object->function();
// and, if you've been paying attention, you know that the method
// Class::function()
// has access to the 'this' pointer of the class
// and thus the 'passing' of this instance information
// is already coded!
// some of your peers would say you must:
delete object;
// others would say this is already accomplished by the task exit.
return 0;
}
If you were to try something like...
file.cc:
#include main.cc
The compiler would be compiling main.cc twice -- which means it would see 2 definitions of everything in main.cc. This will cause you some problems.
It's better design (and actually compiles correctly! Bonus!) to create a custom header file for your classes, and then import this as necessary.
myclasses.h:
Class object;
file.cc:
#include myclasses.h
I got a issue in GraphicsList.cpp in Qt 5.4
#include "GraphicsList.h"
GraphicsList::GraphicsList()
{
_DesignLayerList=new QList<WorkSystem::GraphicShape>();
}
void GraphicsList::Draw(){
for(int i=this->_DesignLayerList->count();i>=0;--i){
WorkSystem::GraphicShape shapeObject=(WorkSystem::GraphicShape)_DesignLayerList[i];
// WorkSystem::GraphicShape shapeObject=_DesignLayerList[i];
shapeObject.Draw();
}
}
QQQ/GraphicsList.cpp:9: error: no matching conversion for C-style cast
from 'QList' to 'WorkSystem::GraphicShape'
WorkSystem::GraphicShape shapeObject=(WorkSystem::GraphicShape)_DesignLayerList[i];
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My GraphicList.h
#ifndef GRAPHICSLIST_H
#define GRAPHICSLIST_H
#include "GraphicShape.h"
class GraphicsList
{
public:
GraphicsList();
~GraphicsList();
void Draw();
private:
QList<WorkSystem::GraphicShape> *_DesignLayerList;
};
#endif // GRAPHICSLIST_H
my GraphicShap.h
#ifndef GRAPHICSHAPE_H
#define GRAPHICSHAPE_H
#include <QDebug>
#include <QPainter>
namespace WorkSystem {
class GraphicShape
{
public:
GraphicShape();
~GraphicShape();
QColor _penColor;
virtual void Draw();
};
}
#endif // GRAPHICSHAPE_H
My GraphicShape.cpp
#include "GraphicShape.h"
#include <QDebug>
WorkSystem::GraphicShape::GraphicShape()
{
_penColor=Qt::white;
}
void WorkSystem::GraphicShape::Draw(){
qDebug()<<"DrawDrawDrawDraw";
}
WorkSystem::GraphicShape::~GraphicShape()
{
}
Please give me any suggestion.
shapeLine.h
#ifndef SHAPELINE_H
#define SHAPELINE_H
#include <QDebug>
#include "GraphicShape.h"
namespace WorkSystem {
class shapeLine : public GraphicShape
{
public:
shapeLine();
~shapeLine();
protected:
void Draw();
};
}
#endif // SHAPELINE_H
shapeLine.cpp
...
The problem appears to be a bit of a misuse of pointers. If you look at the declaration for your _DesignLayerList member:
QList<WorkSystem::GraphicShape> *_DesignLayerList;
You are not declaring an actual QList instance. Instead, you are declaring a pointer to a QList. Thus when you use _DesignLayerList[i], you aren't actually trying to look into the list, but instead doing pointer arithmetic to look up another QList instance, which is not what you are expecting.
Instead, you should declare your member variable without the star, meaning will be an actual instance of a QList rather than a pointer to a QList:
QList<WorkSystem::GraphicShape> _DesignLayerList;
This will then function as expected. I would also recommend reviewing your understanding of the difference between pointers and values, as this is a fundamental of C++. In modern C++, it is recommended to avoid the use of raw pointers as much as possible and instead use smart pointers, references, and value types as they are generally more appropriat and safer.
An alternative, if you insist on using pointers, is to perform a lookup by first de-referencing the pointer so you are referring to the QList instance it points to. However, I would not recommend this as it adds overhead and additional complexity for no benefit:
shapeObject = (*DesignLayerList)[i]
As an example of the problems common to using raw pointers like this: while you create the QList instance, you never actually delete it and as such this code leaks memory.