When I run the following code and press the enter button, I get a Segmentation Fault.
I've searched everywhere on the internet, but I can't find the problem. I'm quite new to C++/Qt.
The base class:
stack.h
#ifndef STACK_H
#define STACK_H
template <class T> class stack
{
public:
stack();
virtual T pop() = 0;
virtual void push(T i) = 0;
};
#endif // STACK_H
stack.cpp
#include "stack.h"
template<class T> stack<T>::stack()
{
}
arraystack.h
#ifndef ARRAYSTACK_H
#define ARRAYSTACK_H
#include "stack.h"
template <class T> class arraystack : public stack<T>
{
public:
arraystack();
T pop();
void push(T i);
};
#endif // ARRAYSTACK_H
arraystack.cpp
#include "arraystack.h"
#include <QDebug>
template<class T> arraystack<T>::arraystack()
{
}
template<class T> T arraystack<T>::pop(){
qDebug() << "popping bad";
}
template<class T> void arraystack<T>::push(T i){
qDebug() << "pushing shit";
}
The part that calls the pop-Function:
calculator.h
// ...
private:
Ui::calculator *ui;
arraystack<int> *h;
bool integer;
// ...
calculator.cpp
// ...
void calculator::on_b_enter_clicked()
{
h->pop();
}
// ...
Error:
The inferior stopped because it received a signal from the Operating System
Signal name: SIGSEGV
Signal meaning: Segmentation Fault
This code:
A.h
template <typename T>
class A
{
public:
A(){}
virtual void f1() = 0;
};
template <typename T>
class B: public A<T>
{
public:
B(){}
void f1(){}
};
main.cpp
#include "A.h"
int main ()
{
A<int> *a = new B<int>();
a->f1();
}
Compiles and works, because all template functions are defined in header file. If you want to split the declaration and the definition, you can use one of these methods:
Include the cpp file at the bottom of your header file
Include the cpp file in main.cpp
Related
I have a class A with the following declaration (A.h file):
#ifndef __A_DEFINED__
#define __A_DEFINED__
class A
{
public:
template<typename T> inline void doThat() const;
};
#endif
and a class B deriving from that class (B.h file):
#ifndef __B_DEFINED__
#define __B_DEFINED__
#include <iostream>
#include "A.h"
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
#endif
So far, so good. My issue is that the function A::doThat() uses B::doThis():
template<typename T> inline void A::doThat() const { B b; b.doThis(); }
Usually, the circular dependency would not be an issue because I would just define A::doThat() in the .cpp file. In my case however, doThat is a template function so I can't do that.
Here are the solutions I have envisioned so far:
Defining the template function A::doThat() in a .cpp file. The issue with that is that I need to instantiate explicitly all the calls with various template arguments (there might be many in the real case).
After the declaration of the A class in A.h, add #include "B.h" and then define the A::doThat() function. This works fine in visual studio but g++ does not like it.
Is there a neat way to solve this problem?
EDIT: In the real case, there is not just one child class B, but several (B, C, D, etc.) The function A::doThat() depends on all of them. The function B::doThis() is also templated.
A default template parameter for the B class could work:
#include <iostream>
// include A.h
class B;
class A
{
public:
template<typename T, typename U = B> inline void doThat() const
{
U b; b.doThis();
}
};
// include B.h
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
// main
int main()
{
A a;
a.doThat<int>();
}
Usually the best way to allow a parent to call a child function is to declare the function as a pure virtual function in the parent and override it in the children.
#include <iostream>
class A
{
public:
virtual ~A() = default;
template<typename T> inline void doThat() const
{
// do some other stuff
doThis();
}
virtual void doThis() const = 0; // pure virtual function
};
class B: public A
{
public:
void doThis() const override
{
std::cout << "do this!" << std::endl;
}
};
int main()
{
B b;
A* ap = &b;
ap->doThat<int>();
}
The following does work with g++:
File A.h:
#ifndef __A_DEFINED__
#define __A_DEFINED__
class A
{
public:
template<typename T> inline void doThat() const;
};
#include "B.h"
template<typename T> inline void A::doThat() const { B b; b.doThis(); }
#endif
File B.h:
#include <iostream>
#include "A.h"
// We check for the include guard and set it AFTER the inclusion of A.h
// to make sure that B.h is completely included from A.h again.
// Otherwise the definition of A::doThat() would cause a compiler error
// when a program includes B.h without having included A.h before.
#ifndef __B_DEFINED__
#define __B_DEFINED__
class B : public A
{
public:
void doThis() const { std::cout << "do this!" << std::endl; }
};
#endif
File test_A.cpp:
// In this test case we directly include and use only A.
#include "A.h"
#include "A.h" // We test whether multiple inclusion causes trouble.
int main() {
A a;
a.doThat<int>();
}
File test_B.cpp:
// In this test case we directly include and use only B.
#include "B.h"
#include "B.h" // We test whether multiple inclusion causes trouble.
int main() {
B b;
b.doThat<int>();
b.doThis();
}
Alternative Idea:
I do not know whether you (or some coding conventions) insist on separate header files for each class, but if not the following should work:
You can put the definitions of class A and class B and of the member function template A::doThat<typename>() (in this order) together in one header file AandB.h (or whatever name you like).
This cries for polymorphism. There are two options using polymorphism:
Dynamic polymorphism, i.e. make A an abstract base class and call doThis() virtually:
struct A
{
virtual void do_this() const = 0;
template<typename T>
void doThat() const { doThis(); }
};
struct B : A
{
void doThis() const override { /* ... */ }
};
Of course, this only works if doThis() is not templated. If you need that, you could use
Static polymorphism, i.e. CRTP, when
template<typename Derived>
struct A
{
template<typename T>
void doThat() const { static_cast<const Derived*>(this)->template doThis<T>(); }
};
struct B : A<B>
{
template<typename T>
void doThis() const { /* ... */ }
};
If (as in your example code) B::doThis() is not called for the same object, but for some temporary, you could
template<typename typeB>
struct A
{
template<typename T>
void doThat() const { typeB b; b.template doThis<T>(); }
};
I was looking for a Singleton Qt implementation and found this. but I have some question about it.
What is the purpose of making create a QBasicAtomicPointer ?
What is the point in qCallOnce of using testAndSetRelaxed if previously we have used fetchAndStoreAcquire ? Isn't the acquire semantic already preventing any memory reordering after it ?
What is the purpose of the qCallOncePerThread function ? Isn't qCallOnce already thread-safe ?
I copy the contents of the suggested implementation here:
call_once.h
#ifndef CALL_ONCE_H
#define CALL_ONCE_H
#include <QtGlobal>
#include <QAtomicInt>
#include <QMutex>
#include <QWaitCondition>
#include <QThreadStorage>
#include <QThread>
namespace CallOnce {
enum ECallOnce {
CO_Request,
CO_InProgress,
CO_Finished
};
Q_GLOBAL_STATIC(QThreadStorage<QAtomicInt*>, once_flag)
}
template <class Function>
inline static void qCallOnce(Function func, QBasicAtomicInt& flag)
{
using namespace CallOnce;
#if QT_VERSION < 0x050000
int protectFlag = flag.fetchAndStoreAcquire(flag);
#elif QT_VERSION >= 0x050000
int protectFlag = flag.fetchAndStoreAcquire(flag.load());
#endif
if (protectFlag == CO_Finished)
return;
if (protectFlag == CO_Request && flag.testAndSetRelaxed(protectFlag,
CO_InProgress)) {
func();
flag.fetchAndStoreRelease(CO_Finished);
}
else {
do {
QThread::yieldCurrentThread();
}
while (!flag.testAndSetAcquire(CO_Finished, CO_Finished));
}
}
template <class Function>
inline static void qCallOncePerThread(Function func)
{
using namespace CallOnce;
if (!once_flag()->hasLocalData()) {
once_flag()->setLocalData(new QAtomicInt(CO_Request));
qCallOnce(func, *once_flag()->localData());
}
}
#endif // CALL_ONCE_H
singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
#include <QtGlobal>
#include <QScopedPointer>
#include "call_once.h"
template <class T>
class Singleton
{
private:
typedef T* (*CreateInstanceFunction)();
public:
static T* instance(CreateInstanceFunction create);
private:
static void init();
Singleton();
~Singleton();
Q_DISABLE_COPY(Singleton)
static QBasicAtomicPointer<void> create;
static QBasicAtomicInt flag;
static QBasicAtomicPointer<void> tptr;
bool inited;
};
template <class T>
T* Singleton<T>::instance(CreateInstanceFunction create)
{
Singleton::create.store(create);
qCallOnce(init, flag);
return (T*)tptr.load();
}
template <class T>
void Singleton<T>::init()
{
static Singleton singleton;
if (singleton.inited) {
CreateInstanceFunction createFunction = (CreateInstanceFunction)Singleton::create.load();
tptr.store(createFunction());
}
}
template <class T>
Singleton<T>::Singleton() {
inited = true;
};
template <class T>
Singleton<T>::~Singleton() {
T* createdTptr = (T*)tptr.fetchAndStoreOrdered(nullptr);
if (createdTptr) {
delete createdTptr;
}
create.store(nullptr);
}
template<class T> QBasicAtomicPointer<void> Singleton<T>::create = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
template<class T> QBasicAtomicInt Singleton<T>::flag = Q_BASIC_ATOMIC_INITIALIZER(CallOnce::CO_Request);
template<class T> QBasicAtomicPointer<void> Singleton<T>::tptr = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
#endif // SINGLETON_H
How to use
// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
class MyClass : public QObject
{
Q_OBJECT
private:
MyClass(QObject* parent = 0);
static MyClass* createInstance();
public:
~MyClass();
static MyClass* instance();
};
#endif // MYCLASS_H
// myclass.cpp
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include "singleton.h"
MyClass::MyClass(QObject* parent):
QObject(parent)
{
}
MyClass* MyClass::createInstance()
{
return new MyClass();
}
MyClass::~MyClass()
{
}
MyClass* MyClass::instance()
{
return Singleton<MyClass>::instance(MyClass::createInstance);
}
#endif // MYCLASS_H
main.cpp
#include <QTextStream>
#include "myclass.h"
#define MyClassInstance Singleton<MyClass>::instance()
int main(int argc, char* argv[])
{
QTextStream(stdout) << MyClass::instance()->metaObject()->className() << endl;
return 0;
}
I think that is will be enough to use next singleton implementation. As I remember, C++11 gurantees that there will be only one instancing/initialization for a static variable.
Original problem was in case, when more than one thread tries to access an instance in same time and there were possible a situation, when singleton was created twice.
template <typename T, typename D = T>
class Singleton
{
friend D;
static_assert(std::is_base_of_v<T, D>, "T should be a base type for D");
public:
static T& instance();
private:
Singleton() = default;
~Singleton() = default;
Singleton( const Singleton& ) = delete;
Singleton& operator=( const Singleton& ) = delete;
};
template <typename T, typename D>
T& Singleton<T, D>::instance()
{
static D inst;
return inst;
}
// Usage:
class MyClass : public Singleton<MyClass>
{
public:
void foo(){}
};
// Access:
MyClass::instance().foo();
Main concept of using Singleton pattern is to restrict the instantiation to certain number of objects, in common use to one.
Q1 : Atomic pointer
Atomic operations are done without interruption , so handled multi-thread instance calls.
Q2 : point of qCallOnce
This function checks if any other threads are executing and if so wait for CO_finished flag in
do {
QThread::yieldCurrentThread();
}
while (!flag.testAndSetAcquire(CO_Finished, CO_Finished));
Q3 : point of qCallOncePerThread
if (!once_flag()->hasLocalData()) {
once_flag()->setLocalData(new QAtomicInt(CO_Request));
I think to handle LocalData of singleton class per each thread instacnes
I'm trying to make use of polymorphism. Basically, there's a class-name missing in the middle of the code. As I'm not used to templates, could someone give me a clue? Thank you
#ifndef TEMPLATE_H``
#define TEMPLATE_H
using namespace std;
template <class T>
class Template
{
public:
Template(int);
virtual ~Template();
virtual void push(T val);
T pop;
virtual bool isFull();
virtual bool isEmpty();
virtual void sizeOf(T val) ;
protected:
private:
int top,size;
};
#endif // TEMPLATE_H
#ifndef STACK_H
#define STACK_H
/***LIFO***/
using namespace std;
template <class S>
class stack: public Template{ // HERE, it says it's missing an expected class
-name before {
public:
stack();
virtual ~stack();
protected:
private:
};
#endif // STACK_H
stack should inherit from Template<S>, not Template.
Template is not a class. It is a class template. Template<int> would be a class, or Template<std::string>. You cannot inherit from a class template, only from a class (or struct).
I have several classes in a project I'm working on; the first is a Solver class, originally with a function template whose full definition is in the Solver header file, like so (just showing the bare necessities):
solver.h
class Solver {
public:
template<typename T>
void solve(T t);
}
template<typename T>
void Solver::solve(T t) {
// implementation here
}
Now, class A is used as template parameter for the solve function template as follows:
A.h
#include "solver.h"
class A {
private:
Solver s; //s is instantiated in constructor
public:
void doSomething();
}
A.cpp
void A::doSomething() {
s.solve<A&>(*this);
}
So this is all fine and dandy as it is now, but for the purposes of the project, I need to move the definition of the solve() function template into an implementation file (solver.cpp) from the header file. As I understand it, I can do this as long as I add lines that explicitly state what types will be used with the function template, as follows:
solver.cpp
template<typename T>
void Solver::solve(T t) {
// implementation here
}
template void Solver::solve<A&>(A& a);
However this doesn't work when I try to compile solver, because in order to specify A as a type I want to use as a template parameter in solve.cpp, I need to have A not be an incomplete type. But A requires Solver in order to even compile - so I believe I have a circular dependency. Is there any way I can get around this issue?
I'm relatively new to all this, so take it easy on me please :) Much thanks.
Samoth is nearly right, you need class A; ("forward declaration"). But only before you use it, not before the Solver class:
Edited In response to comments, your minimal code sample was too minimal :) The real problem was Header Guards:
#ifndef SOLVER_H_INCLUDED_
#define SOLVER_H_INCLUDED_
class Solver {
public:
template<typename T>
void solve(T t);
};
#endif // SOLVER_H_INCLUDED_
And
// A.h
#ifndef A_H_INCLUDED_
#define A_H_INCLUDED_
#include "Solver.h"
class A {
private:
Solver s; //s is instantiated in constructor
public:
void doSomething();
};
#endif // A_H_INCLUDED_
// Solver.cpp
#include "Solver.h"
#include "A.h"
template<typename T>
void Solver::solve(T t) {
// implementation here
}
// explicit instantiations
template void Solver::solve<int>(int);
// ...
template void Solver::solve<A&>(A&);
This will work
// main.cpp
#include "A.h"
int main()
{
A a;
a.doSomething();
}
The best way to pass-by circular dependencies is to do this :
class A; // before the class Solver
class Solver {
public:
template<typename T>
void solve(T t);
}
template<typename T>
void Solver::solve(T t) {
// implementation here
}
What you can do is:
solver.h
#ifndef SOLVER_H_INCLUDED_
#define SOLVER_H_INCLUDED_
class Solver {
public:
template<typename T>
void solve(T t);
};
#include "solver.cpp"
#endif
solver.cpp
#include "solver.h"
template<typename T>
void Solver::solve(T t) {
// implementation here
}
and a.hpp
#ifndef A_H_INCLUDED_
#define A_H_INCLUDED_
#include "solver.h"
class A {
private:
Solver s; //s is instantiated in constructor
public:
void doSomething()
{
s.solve(*this);
}
};
#endif
I have two classes. Each has a pointer pointing to the other class. So I have to use forward class declaration in one of them. This method runs well until I need to use a function with template (which I have to write both the declaration and implementation in the header file).
More specifically, my codes are something like the following files. These files got compiled without problems on Windows by MS Visual Studio 2010. But when I compile them on Mac by XCode 4.3.2, I got an error of "Member access into incomplete type 'ClassB'" in file ClassA.h.
Can anyone tell me how to make it compilable on Mac with XCode?
file ClassA.h
#ifndef CLASS_A
#define CLASS_A
//#include "ClassB.h"
class ClassB;
class ClassA
{
public:
ClassA();
template <typename T>
void funcA(T *t);
int iNum;
ClassB *pB;
};
template <typename T>
void ClassA::funcA(T *t)
{
iNum = *(int*)t;
iNum += pB->iNum;
}
#endif
file ClassA.cpp
#include "ClassA.h"
ClassA::ClassA()
{
iNum = 1;
}
file ClassB.h
#ifndef CLASS_B
#define CLASS_B
#include "ClassA.h"
class ClassB
{
public:
ClassB();
template <typename T>
void funcB(T *t);
int iNum;
ClassA *pA;
};
template <typename T>
void ClassB::funcB(T *t)
{
iNum = *(int*)t;
iNum -= pA->iNum;
}
#endif
file ClassB.cpp
#include "ClassB.h"
ClassB::ClassB()
{
iNum = 2;
}
Main file
#include <stdio.h>
#include "ClassA.h"
#include "ClassB.h"
int main(void)
{
ClassA objA;
ClassB objB;
objA.pB = &objB;
objB.pA = &objA;
int a = 11;
int b = 22;
objA.funcA(&a);
objB.funcB(&b);
printf("Class A: %d, %d\n", objA.iNum, objA.pB->iNum);
printf("Class B: %d, %d\n", objB.iNum, objB.pA->iNum);
return 0;
}
You access pB->iNum in your function definition, which is not known from A class since you did not include classB.h.
Foward declaration helps you to define classes, you can then include your header files. Try something like this:
#ifndef CLASS_A
#define CLASS_A
class ClassB;
class ClassA
{
public:
ClassA();
template <typename T>
void funcA(T *t);
int iNum;
ClassB *pB;
};
#include "ClassB.h"
template <typename T>
void ClassA::funcA(T *t)
{
iNum = *(int*)t;
iNum += pB->iNum;
}
#endif
And do the same in classB.h