【发布时间】:2017-08-14 22:17:53
【问题描述】:
我正在尝试创建一个对象引用模板类,它将保存类指针并且一切正常,除非尝试将基类 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 ©) { 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 是一个模板,它包含一个指向已定义类的指针,并用作新类型。除了尝试将基类转换为派生类外,它工作正常。查看如何使用基类引用调用 func5()。第一次尝试是所需的语法。如果我在引用类中使用 ptr,它会起作用,但这是不希望的。
我只是觉得我缺少一个接线员之类的东西。
谢谢。
【问题讨论】:
-
你的代码中有很多被误导的东西。
#define null nullptr不 不要那样做。operator BaseType*() {return (BaseType*)this;}完全没用;使用static_cast<BaseType*>(&myObject)。您继续使用 C 风格的演员表进行转换;使用 C++ 风格的演员表。最后,ObjRef似乎完全不需要。 -
@Bo - 如果基类指针指向派生类,则可以。即使有多重继承也是可能的,但不明智。
-
@Peter - 好的,你欺骗了我,隐藏了指针类型的
*并使Derived不是从Base派生的。
标签: c++ inheritance casting