c ++类型转换基础ptr到派生的ptr保存在引用类

时间:2017-08-14 22:17:54

标签: c++ inheritance casting

我试图创建一个包含类指针的对象引用模板类,除了在尝试将类型转换类ptr键入派生类ptr时,一切正常。

以下是代码:

#include <stdio.h>
#include <stdlib.h>

#define null nullptr

class BaseType;
class DerivedType;

template<class T>
class ObjRef {
public:
  T *ptr = null;  //should be private

  ObjRef& operator= (T *ptr) { this->ptr = ptr; return *this; }
  ObjRef& operator= (const ObjRef &ref) { ptr = ref.ptr; return *this; }
  operator T*() const {return ptr;}
  operator T() const {return *ptr;}
  ObjRef() {}
  ObjRef(const ObjRef &copy) { ptr = copy.ptr; }
#ifdef VOID_FIX
  ObjRef(void*p) { ptr = (T*)p; }  //this could fix the bug except would not work with multiple inheritance and is not safe
#else
  ObjRef(T*p) { ptr = p; }
#endif
  ~ObjRef() { }
  T* operator->() const {return ptr;}  //unfortunately operation. (dot) can not be overloaded - that would make life too easy :(
};

class Object {};

class BaseType : public Object {
public:
  int baseValue;
};

class DerivedType : public BaseType {
public:
  operator BaseType*() {return (BaseType*)this;}  //helpful?
  int derivedValue;
};

typedef ObjRef<BaseType> Base;
typedef ObjRef<DerivedType> Derived;

void func4(Base x) {
  x->baseValue = 1;
}

void func5(Derived x) {
  x->derivedValue = 1;
}

int main() {
  Base b = null;
  Derived d = null;
  Base x;

  x = d;  //no type cast needed
  func4((Base)d);  //cast from Derived to Base class - no problem

  b = d;  //base does point to derived
//  func5((Derived)b);  //cast from Base to Derived - does not work (desired syntax)
  // with gcc -fpermissive can be used to change error to warning - can I silence the warning ?
  // what would cl.exe equivalent be?

//  func5((Derived)b.ptr);  //invalid cast, ptr should be private
//  func5((DerivedType*)b);  //invalid cast, ptr should be private
//  func5(dynamic_cast<DerivedType*>(b.ptr));  //invalid cast, source type is not polymorphic, ptr should be private

  func5((DerivedType*)b.ptr);  //this works but is undesired and ptr should be private
  func5(static_cast<DerivedType*>(b.ptr));  //works but again is undesired and ptr should be private

  return 0;
}

在示例ObjRef&lt;&gt;中是一个模板,它包含指向所定义类的指针,并用作新类型。除了尝试将基类转换为派生类之外,它工作正常。看看如何使用基类引用调用func5()。第一次尝试是所需的语法。如果我在引用类中使用ptr它将起作用,但这是不希望的。

我只是觉得我错过了一个操作员或什么的。

感谢。

1 个答案:

答案 0 :(得分:0)

像往常一样,我在发布后不久就找到了解决方案 ObjRef&lt;&gt; class需要知道基类。 这是新代码:

#include <stdio.h>
#include <stdlib.h>

#define null nullptr

class BaseType;
class DerivedType;

template<class T>
class ObjRef {
public:
  T *ptr = null;

  ObjRef& operator= (auto *ptr) { this->ptr = ptr; return *this; }
  ObjRef& operator= (const ObjRef<auto> &ref) { ptr = ref.ptr; return *this; }
  operator T*() const {return ptr;}
  ObjRef() {}
  ObjRef(const ObjRef<auto> &copy) { ptr = (T*)copy.ptr; }
  ObjRef(T*p) { ptr = p; }
  ~ObjRef() { }
  T* operator->() const {return ptr;}  //unfortunately operator. (dot) can not be overloaded - that would make life too easy :(
};

class Object {};

class BaseType : public virtual Object {
public:
  int baseValue;
};

class InterfaceType : public virtual Object {
public:
  virtual void func7() {
    printf("it works!\n");
  };
};

typedef ObjRef<InterfaceType> Interface;

class DerivedType : public BaseType, public InterfaceType {
public:
  int derivedValue;
};

typedef ObjRef<BaseType> Base;
typedef ObjRef<DerivedType> Derived;

void func4(Base x) {
  x->baseValue = 1;
}

void func5(Derived x) {
  x->derivedValue = 2;
}

void func6(Interface x) {
  x->func7();
}

int main() {
  Base b = new BaseType();
  Derived d = new DerivedType();
  Base x;

  x = d;  //no type cast needed
  func4((Base)d);  //cast from Derived to Base class - no problem
  printf("BaseValue=%d\n", d->baseValue);

  b = d;  //base does point to derived
  func5((Derived)b);  //cast from Base to Derived - works now!
  printf("DerivedValue=%d\n", d->derivedValue);

  func6(d);

  return 0;
}

更新:发布了一个适用于任何继承级别的新版本,但现在需要C ++ 14(自动关键字)

UPDATE#2 :现在使用单个ObjRef类(仍然需要C ++ 14)。不幸的是,cl.exe并不支持自动&#39;模板参数:(

更新#3 :添加了一些测试代码以证明其有效。