我试图创建一个包含类指针的对象引用模板类,除了在尝试将类型转换类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&lt;&gt;中是一个模板,它包含指向所定义类的指针,并用作新类型。除了尝试将基类转换为派生类之外,它工作正常。看看如何使用基类引用调用func5()。第一次尝试是所需的语法。如果我在引用类中使用ptr它将起作用,但这是不希望的。
我只是觉得我错过了一个操作员或什么的。
感谢。
答案 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> ©) { 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 :添加了一些测试代码以证明其有效。