模板类的多继承构造函数与此指针不起作用?

时间:2018-06-20 16:09:24

标签: c++ templates inheritance c++14 this-pointer

我有一个牢记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

目前暂时没有编译错误。我还有一个带有operator.hpp的文件,该文件仅包含每个运算符的模板定义。

输出 当我运行可执行文件时,得到以下输出,我可能不明白为什么?我尝试了各种可能的方式来了解。我还在不同版本的不同系统上运行。

ohk hello  there  checking  hello
ohk hello  here ohk hello  here

这是怎么回事?为什么我的继承调用不正确?我知道我不应该传递此指针,因为它不安全,但是我认为我没有其他选择。

我的问题

  1. Object<T>::Object(Class<T>& myReference)仅被调用一次,但应被调用三次。
  2. 在我看来,有四个对象创建,它必须是3或5(t1.cpp中的a和b以及每个类中的UNIEQUEID初始化。
  3. 为什么这在构造函数调用的Class.cpp文件中不起作用?
  4. 有什么方法可以检查是否可以使Object类调用Object<T>::Object()构造函数,以便使T = Object class?

1 个答案:

答案 0 :(得分:0)

您正在使用虚拟继承。派生最多的类负责初始化其所有虚拟基类。

写作时

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构造函数,该构造函数与{ {1}}。


您如何计算四个实例?在显示的输出中,单词Object(*this)出现一次,单词there出现两次,总共构造了here的三个实例。它们是Uint_32ab


我不确定我是否理解你的问题4.你在问你是否可以写,比如说,

Uint_32::UNIQUEID

?我不明白为什么不这样做,但是您可以轻松地尝试一下并自己看看。