Конструктор множественного наследования класса шаблона с этим указателем не работает?
У меня есть очень простой код, помня о Java. Я создал класс Object и Class, но в шаблоне.
Object.hpp
#ifndef _OBJECT_HPP_
#define _OBJECT_HPP_
namespace library{
template<class T> class Object;
template<class T> class Class;
class Uint_32;
template<class T>
class Object{
public:
const static Uint_32& UNIQUEID;
private:
const Class<T>& myClass;
const static Class<T>& ref;
protected:
Object(Class<T>& myReference);
Object();
};
}
#endif
Object.cpp
#include "include//lang//template//Object.hpp"
#include "include//lang//template//Class.hpp"
#include "include//lang//Uint_32.hpp"
#include "iostream"
using namespace std;
using namespace library;
template<class T>const Uint_32& Object<T>::UNIQUEID=Uint_32(1);
template<class T>const Class<T>& Object<T>::ref=Class<T>();
template<class T>
Object<T>::Object(Class<T>& myReference):myClass(myReference){cout<<"
checking ";}
template<class T>
Object<T>::Object():myClass(ref){cout<<"ohk";}
Class.hpp
#ifndef _CLASS_HPP_
#define _CLASS_HPP_
#include"include//lang//Object.hpp"
namespace library{
template<class T>
class Class:public virtual Object<T>{
public:
Class();
const static Uint_32& UNIQUEID;
};
}
#endif
Class.cpp
#include "include//lang//template//Class.hpp"
#include "include//lang//Uint_32.hpp"
using namespace library;
template<class T>const Uint_32& Class<T>::UNIQUEID=Uint_32(2);
template<class T>
Class<T>::Class():Object(*this){
cout<<" hello ";
}
Uint_32.hpp
#ifndef _UINT_32_HPP_
#define _UINT_32_HPP_
#include "include//lang//Class.hpp"
#include "include//lang//Operators.hpp"
namespace library{
class Uint_32:public virtual Class<Uint_32>{
public:
Uint_32();
Uint_32(const int&&);
friend Uint_32& operator+(const Uint_32& a,const Uint_32& b);
friend Uint_32& operator<<(const Uint_32& a,const int& b);
const static Uint_32& UNIQUEID;
private:
int value;
};
}
#endif
Uint_32.cpp
#include "include//lang//Uint_32.hpp"
using namespace library;
const Uint_32& Uint_32::UNIQUEID=Uint_32(3);
Uint_32::Uint_32():Class<Uint_32>(){
value=0;
cout<<" here ";
}
Uint_32::Uint_32(const int&& val):Class<Uint_32>(){
value=val;
cout<<" there ";
}
t1.cpp
#include "include//lang//Uint_32.hpp"
using namespace library;
int main()
{
cout<<"\n";
Uint_32 a,b;
return 0;
}
Команда компиляции:
g++ -std=c++14 -I. -c src//lang//Uint_32.cpp -o obj//lang//Uint_32.o
g++ -std=c++14 -I. src//test//t1.cpp obj//lang//Uint_32.o -o bin//test
теперь нет ошибки компиляции. У меня есть еще один файл с tors.hpp, который просто содержит определение шаблона для каждого оператора.
ВЫХОД, когда я запускаю исполняемый файл, я получаю следующий вывод и, вероятно, не могу понять, почему? Я перепробовал все возможные способы узнать. Я также использую другую систему с другой версией.
ohk hello there checking hello
ohk hello here ohk hello here
Что здесь происходит? Почему мое наследство не вызывает правильно? Я знаю, что не должен передавать этот указатель, поскольку это небезопасно, но я думаю, что у меня нет альтернативы.
Мои проблемы
Object<T>::Object(Class<T>& myReference)
вызывается только один раз, но это следует называть трижды.- На мой взгляд, существует четыре объекта создания, это должно быть либо 3, либо 5 (a и b в t1.cpp и инициализация UNIEQUEID в каждом классе.
- почему это не работает в файле Class.cpp при вызове конструктора?
- Есть ли способ проверить, могу ли я сделать объектный класс для вызова
Object<T>::Object()
конструктор так что T = Object класс?
1 ответ
Вы используете виртуальное наследование. Самый производный класс отвечает за инициализацию всех своих виртуальных базовых классов.
Когда ты пишешь
Uint_32::Uint_32(const int&& val):Class<Uint_32>(){ ... }
Вы, кажется, ожидаете Uint_32
конструктор для вызова Class<Uint_32>()
конструктор, и что в свою очередь, чтобы позвонить Object(*this)
, Но это не то, что происходит. поскольку Object
это виртуальный базовый класс, Uint_32
отвечает за его инициализацию, а не Class
, И с тех пор Uint_32
не упоминает об этом в своем списке инициализатора, Object
Используется конструктор по умолчанию (а не однопараметрический).
Это один призыв к Object(Class<T>&)
происходит от template<class T>const Class<T>& Object<T>::ref=Class<T>();
, Это единственное место, где вы создаете экземпляр Class
как наиболее производный объект (в отличие от подобъекта базового класса другого объекта), что делает его ответственным за вызов Object
конструктор, который он делает с Object(*this)
,
Как вы считаете четыре экземпляра? В выводе вы показываете слово there
встречается один раз и слово here
в два раза, в общей сложности три случая Uint_32
строится. Те a
, b
а также Uint_32::UNIQUEID
,
Я не уверен, что понимаю ваш вопрос 4. Вы спрашиваете, можете ли вы написать, скажем,
Object<Object<int>> obj;
? Я не понимаю, почему нет, но вы можете легко попробовать и убедиться в этом.