My MouseInteractorStyle : undefined reference to `vtkInteractorStyleZoom ::New()' - c++

i am on a vtk project
I wanted to write my own mouse interactor style
i writed this class
vtkInteractorStyleZoom.h
#include <vtkSmartPointer.h>
#include <vtkInteractorStyleTrackballCamera.h>
class vtkInteractorStyleZoom: public vtkInteractorStyleTrackballCamera
{
public:
static vtkInteractorStyleZoom* New();
vtkTypeMacro(vtkInteractorStyleZoom , vtkInteractorStyleTrackballCamera);
virtual void OnLeftButtonDown();
};
vtkInteractorStyleZoom.cpp
#include "vtkInteractorStyleZoom.h"
vtkStandardNewMacro(vtkInteractorStyleZoom);
void vtkInteractorStyleZoom::OnLeftButtonDown()
{
this->StartDolly();
}
and this the functions where i use this class
void ReadDICOMSeriesQt::on_ZoomButton_clicked()
{
vtkSmartPointer<vtkInteractorStyleZoom> Style =
vtkSmartPointer<vtkInteractorStyleZoom>::New();
ui->qvtkWidget->GetRenderWindow()->GetInteractor()-
>SetInteractorStyle(Style);
}
and when i compiled my project with cmake i had a this problem
CMakeFiles\ReadDICOMSeriesQt.dir/objects.a(ReadDICOMSeriesQt.cxx.obj): In function ZN15vtkSmartPointerI22vtkInteractorStyleZoomE3NewEv':
C:/VTK/VTK-7.0.0/Common/Core/vtkSmartPointer.h:117: undefined reference tovtkInteractorStyleZoom::New()'
i dont know if there is any problem with cmake (maybe i must change somethings in my CMakeLists.txt)
is there anyone who can help me ?

What you are missing is the constructor definition. The constructor must take no arguments, so that the object factory mechanism works. Make it private, because noone should call it directly.
You should also disable copy semantic of your class. I.e.
class vtkInteractorStyleZoom : public vtkInteractorStyleTrackballCamera
{
public:
static vtkInteractorStyleZoom* New();
vtkTypeMacro(vtkInteractorStyleZoom, vtkInteractorStyleTrackballCamera);
virtual void OnLeftButtonDown();
private:
vtkInteractorStyleZoom() { /* definition, if any */ }
vtkInteractorStyleZoom(const vtkInteractorStyleZoom&) = delete;
void operator =(const vtkInteractorStyleZoom&) = delete;
};
Also, you should #include <vtkObjectFactory.h> in the .cpp file -- that's where vtkStandardNewMacro() is defined.
Then make sure that the caller module (ReadDICOMSeriesQt) links against the library which vtkInteractorStyleZoom is part of.

Related

C++ How to correctly expose a Shared Library via header

I've designed and developed a SHARED library and would like to distribute it, but I don't want to expose the private methods and private attributes.
Here is what I have tried with no success:
Full header, used to build the library mylib.so:
namespace MYNAMESPACE{
enum class MyReturnCode {
Success = 1,
MyRetCode01,
MyRetCode02
};
class MyException {
public:
MyException(
MYNAMESPACE::MyReturnCode _code,
std::string _message);
MYNAMESPACE::MyReturnCode code;
std::string message;
};
class MyClass {
public:
MyClass();
~MyClass();
void initialize();
std::string function01();
std::string function02();
int attribute01;
float attribute02;
private:
std::string function03();
int attribute03;
float attribute04;
};
}
The header I designed to use when sharing mylib.so with others is similar to this one, but without the private section.
When I call the function initialize, the attributes attribute03 and attribute04 are correctly set and I can use them until some point.
THE ACTUAL PROBLEM WITH ALL THIS SCENARIO
I don't know why, but at some point, attribute03 and attribute04 just get some trash and I have a SIGABRT that ends the execution.
EDITED (2nd time)
After some comments, I went into the following PIMPL solution and now it is working fine.
header my_class_api.hpp, used to distribute with mylib.so
#include <memory>
namespace MY_API {
class MyClassAPI {
public:
virtual ~MyClassAPI() {};
virtual void initialize() = 0;
virtual std::string function01() = 0;
virtual std::string function02() = 0;
static std::shared_ptr<MyClassAPI> get_my_api();
};
}
NEW full header my_class.hpp, used to build the library mylib.so:
#include "my_class_api.hpp"
namespace MYNAMESPACE{
class MyClass : public MY_API::MyClassAPI {
public:
MyClass();
~MyClass() override;
void initialize() override;
std::string function01() override;
std::string function02() override;
private:
std::string function03();
int attribute03;
float attribute04;
};
}
Implementation file my_class.cpp
#include "my_class.hpp"
namespace MY_API {
std::shared_ptr<MyClassAPI> MyClassAPI::get_my_api() {
return std::make_shared<MYNAMESPACE::MyClass>();
}
}
namespace MYNAMESPACE {
MyClass::MyClass() { }
MyClass::~MyClass() { }
void MyClass::initialize() { }
std::string MyClass::function01() { }
std::string MyClass::function02() { }
}
Thanks everybody that helped me! I hope this example helps others too.
As mentioned above, PIMPL is the best solution for that. Qt, for example, uses PIMPL on all its classes to also ensure binary compatibility. That is, when a newer version of a DLL is installed, it is compatible with all old binaries, because the public interface does not change.
https://en.cppreference.com/w/cpp/language/pimpl
The header I designed to use when sharing mylib.so with others is similar to this one, but without the private section.
The header that you use to build the .so shared lib should be the same as the header that you expose to the client. One cannot have private members, and the other not have them. The client will not consider the private members to be part of the class, but when executing a function, it would try to use a memory that does not belong to the instance.
As mentioned, PIMPL is a commonly used solution. In your class's private section you can have a MyClassData* mData; declaration. In your .cpp file, you can define the struct MyClassData, and initiate its members. In the constructor, allocate memory to mData, and in the destructor delete the memory.

How to create a private static const string when using the pimpl idiom

Background
I have been learning how to implement the pimpl idiom using the newer c++11 method described by Herb Sutter at this page: https://herbsutter.com/gotw/_100/
I'm trying to modify this example by adding a member variable to the private implementation, specifically a std::string (although a char* has the same issue).
Problem
This seems to be impossible due to the use of a static const non-integral type. In-class initialization can only be done for integral types, but because it is static it can't be initialized in the constructor either.
A solution to this problem is to declare the private variable in the header file, and initialize it in the implementation, as shown here:
C++ static constant string (class member)
However, this solution does not work for me because it breaks the encapsulation I'm trying to achieve through the pimpl idiom.
Question
How can I hide a non-integral static const variable within the hidden inner class when using the pimpl idiom?
Example
Here is the simplest (incorrect) example I could come up with demonstrating the problem:
Widget.h:
#ifndef WIDGET_H_
#define WIDGET_H_
#include <memory>
class Widget {
public:
Widget();
~Widget();
private:
class Impl;
std::unique_ptr<Impl> pimpl;
};
#endif
Widget.cpp:
#include "Widget.h"
#include <string>
class Widget::Impl {
public:
static const std::string TEST = "test";
Impl() { };
~Impl() { };
};
Widget::Widget() : pimpl(new Impl()) { }
Widget::~Widget() { }
Compilation command:
g++ -std=c++11 -Wall -c -o Widget.o ./Widget.cpp
Note that this example fails to compile because the variable TEST cannot be assigned at declaration due to it not being an integral type; however, because it is static this is required. This seems to imply that it cannot be done.
I've been searching for previous questions/answers to this all afternoon, but could not find any that propose a solution that preserves the information-hiding property of the pimpl idiom.
Solution Observations:
In my example above, I was attempting to assign the value of TEST in the Impl class declaration, which is inside of Widget.cpp rather than its own header file. The definition of Impl is also contained within Widget.cpp, and I believe this was the source of my confusion.
By simply moving the assignment of TEST outside of the Impl declaration (but still within the Widget/Impl definition), the problem appears to be solved.
In both of the example solutions below, TEST can be accessed from within Widget by using
pimpl->TEST
Attempting to assign a different string into TEST, i.e.
pimpl->TEST = "changed"
results in a compiler error (as it should). Also, attempting to access pimpl->TEST from outside of Widget also results in a compiler error because pimpl is declared private to Widget.
So now TEST is a constant string which can only be accessed by a Widget, is not named in the public header, and a single copy is shared among all instances of Widget, exactly as desired.
Solution Example (char *):
In the case of using a char *, note the addition of another const keyword; this was necessary to prevent changing TEST to point to another string literal.
Widget.cpp:
#include "Widget.h"
#include <stdio.h>
class Widget::Impl {
public:
static const char *const TEST;
Impl() { };
~Impl() { };
};
const char *const (Widget::Impl::TEST) = "test";
Widget::Widget() : pimpl(new Widget::Impl()) { }
Widget::~Widget() { }
Solution Example (string):
Widget.cpp:
#include "Widget.h"
#include <string>
class Widget::Impl {
public:
static const std::string TEST;
Impl() { };
~Impl() { };
};
const std::string Widget::Impl::TEST = "test";
Widget::Widget() : pimpl(new Widget::Impl()) { }
Widget::~Widget() { }
Update:
I realize now that the solution to this problem is completely unrelated to the pimpl idiom, and is just the standard C++ way of defining static constants. I've been used to other languages like Java where constants have to be defined the moment they are declared, so my inexperience with C++ prevented me from realizing this initially. I hope this avoids any confusion on the two topics.
#include <memory>
class Widget {
public:
Widget();
~Widget();
private:
class Impl;
std::unique_ptr<Impl> pimpl;
};
/*** cpp ***/
#include <string>
class Widget::Impl {
public:
static const std::string TEST;
Impl() { };
~Impl() { };
};
const std::string Widget::Impl::TEST = "test";
Widget::Widget() : pimpl(new Impl()) { }
Widget::~Widget() { }
You might want to consider making TEST a static function which returns a const std::string&. This will allow you to defined it inline.
You could also replace const by constexpr in your example and it will compile.
class Widget::Impl {
public:
static constexpr std::string TEST = "test"; // constexpr here
Impl() { };
~Impl() { };
};
Update:
Well, it seems that I was wrong... I always store raw string when I want constants.
class Widget::Impl {
public:
static constexpr char * const TEST = "test";
};
Depending on the usage pattern, it might be appropriate or not. If not, then define the variable as explained in the other answer.

Xcode 8.3.1 - Compiler can no longer handle circular references?

I have been developing a C++ game engine for a long time. I have never had any issues with the compiler, or anything like that, until I update to Xcode 8.3.1!
Suddenly, it appears that a default setting was changed when I updated that made it so that the compiler simply cannot handle circular references.
Does anyone know how to set this back, (I tried downgrading Xcode, and it still doesn't work!)
My circular referencing looks something like this:
I have a class called "Object" defined in my code
"Object" includes another class called "Renderer2D"
"Renderer2D" includes another class called "Renderable2D"
"Renderable2D" extends "Object"
My "Object" class:
#pragma once
#include "Graphics/2D/Renderer2D.h"
namespace kineticengine {
class Object {
public:
Object();
virtual ~Object() {}
virtual void render(graphics::Renderer2D* renderer) const;
};
}
My "Renderer2D" class:
#pragma once
#include "Renderable2D.h"
namespace kineticengine {
namespace graphics {
class Renderer2D {
protected:
Renderer2D() {}
public:
virtual void submit(const Renderable2D* renderable) {}; // Error here, "Unknown type name 'Renderable2D', did you mean 'Renderer2D'?"
};
}
}
My "Renderable2D" class:
#pragma once
#include "Renderer2D.h"
#include "../../Object.h"
namespace kineticengine {
namespace graphics {
class Renderable2D : public Object {
public:
Renderable2D() : Object() {}
virtual ~Renderable2D() {}
void render(Renderer2D* renderer) const override {
renderer->submit(this); // Error here "Cannot initialize parameter of type 'const kineticengine::graphics::Renderer2D *' with an rvalue of type 'const kineticengine::graphics::Renderable2D *'"
}
};
}
}
All of my errors are basically variations of "Unknown class [x]" where x is one of the other classes.
Any help would be appreciated!
Renderable2D.h is including Renderer2D.h before defining class Renderable2D, so when Renderer2D.h refers to class Renderable2D, it is not yet defined. Clang is behaving correctly.
One way to break this cycle is to not include headers if you're only going to refer to a class by pointer or reference. You then put a forward declaration for the class in instead of the include directive. This has the added bonus of speeding up compile time as well.

C++ Singleton: `Undefined reference to` error

I am trying to implement a singleton design pattern without memory allocation. I tried searching for a solution but it seems like every solution was for a singleton defined with memory allocation.
I made the constructor private and the only code I added to the header file to make this a singleton design pattern was:
static ParametersServerPC& ParametersServerPC::GetInstance() {
static ParametersServerPC instance;
return instance;
}
This is a derived class from the base class ParametersServerABS which has an empty constructor definition. ParametersServerABS is an abstract class.
When I try to instantiate a ParametersServerPC class in a separate file:
ParametersServerPC& paramServer = ParametersServerPC::GetInstance();
I get this error:
undefined reference to `ParametersServerPC::GetInstance()'
Here are the .cpp and .hpp files:
parameters_server_abs.hpp:
#ifndef PARAMETERS_SERVER_ABS_HPP_
#define PARAMETERS_SERVER_ABS_HPP_
class ParametersServerABS {
public:
ParametersServerABS();
~ParametersServerABS();
virtual bool Load() = 0;
};
#endif
parameters_server_abs.cpp:
#include "mid_level/parameters_server_abs.hpp"
ParametersServerABS::ParametersServerABS() {}
ParametersServerABS::~ParametersServerABS() {}
parameters_server_pc.hpp:
#ifndef PARAMETERS_SERVER_PC_HPP_
#define PARAMETERS_SERVER_PC_HPP_
#include <string>
#include "mid_level/parameters_server_abs.hpp"
class ParametersServerPC: public ParametersServerABS {
public:
~ParametersServerPC();
static ParametersServerPC& GetInstance();
virtual bool Load();
private:
ParametersServerPC(std::string parameterFileName = "parameters.txt");
std::string _parameterFileName;
};
parameters_server_pc.cpp:
#include "mid_level/parameters_server_pc.hpp"
ParametersServerPC::ParametersServerPC(std::string parameterFileName = "parameters.txt") :
_parameterFileName(parameterFileName) {
}
ParametersServerPC::~ParametersServerPC() {
}
static ParametersServerPC& ParametersServerPC::GetInstance() {
static ParametersServerPC instance;
return instance;
}
virtual bool ParametersServerPC::Load() {
return true; // TODO
}
my_test_file.cpp
#include "mid_level/parameters_server_pc.hpp"
ParametersServerPC& paramServer = ParametersServerPC::GetInstance();
undefined reference to `ParametersServerPC::GetInstance()'
This seems to be a linker error. If you can post the output of the compilation console we might narrow this down further.
In the meantime you could check your build system and see if you omitted some source files from compilation.
On the singleton pattern there are already some good answers. More on the topic in a description of the pattern and in a general question about singletons.
It is an acceptable pattern. Here is a MVCE demonstrating the feasability :
#include <iostream>
#include <string>
using namespace std;
class A {
public:
int ival;
string strval;
static A& getInstance();
private:
A(int ival, string strval): ival(ival), strval(strval) {}
A(A& src): ival(src.ival), strval(src.strval) {}
~A() {};
};
A& A::getInstance() {
static A instance(1, "foo");
return instance;
}
int main() {
A& a = A::getInstance();
cout << a.ival << endl;
// A a1 = A::getInstance(); error
// A a2 = a; error
// A a3(2, "bar"); error
return 0;
}
First, mark your ~ParametersServerABS(); destructor virtual to be able to delete objects properly. Second, you need to remove virtual and static keywords from parameters_server_pc.cpp file: they are only for definitions (for your header file).
Next, do it right:
class ParametersServerPC {
// your code
private:
ParametersServerPC(std::string parameterFileName = "parameters.txt");
ParametersServerPC(ParametersServerPC const&) = delete;
void operator=(ParametersServerPC const&) = delete;
};
Singleton means that you can't get copies of an object: you need to forbid using of copy constructor and copy assignment operator.
And anyway I think your problem is in static in your parameters_server_pc.cpp file. Remove it from implementation part (cpp file) in order to fix the problem but LEAVE it in the definition part (header file).

C++ inherit class shows no default constructor

I'm creating a few classes and I decided to create a basic class that other classes will just inherit that basic class
So here is my basic class header
#pragma once
#include "ImageService.h"
class State
{
public:
State( ImageService& is );
~State();
void Update();
};
don't worry about the methods, they aren't the problem.
So now I go ahead and create a IntroState like so (header file)
#pragma once
#include "State.h"
class IntroState : public State
{
public:
IntroState(ImageService& imageService);
~IntroState();
GameState objectState;
};
and here is the cpp file
#include "IntroState.h"
IntroState::IntroState(ImageService& imageService)
{
//error here
}
IntroState::~IntroState()
{
}
at the constructor it is stating "no default constructor for class "State"", now what I think is going on is, the default constructor for State needs a imageService reference passed to it. So how would I pass the imageservice in this constructor to the state constructor?
Your base class has no default constructor, which is what gets implicitly called in your current derived class constructor. You need to explicitly call the base's constructor:
IntroState::IntroState(ImageService& imageService) : State(imageService)
{
}
The usual way:
IntroState::IntroState(ImageService& imageService)
: State(imageService)
{
}
You should call the constructor of State too, like this:
IntroState::IntroState(ImageService& imageService)
: State(imageService) {
}
Tip: Don't use:
#pragma once, use guards!
Example:
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
class A {
int member;
};
#endif /* GRANDFATHER_H */
You can read more about the include guards in wikipedia.
You see #pragma is not standard. Neither became in C++11 (link).