C++ 类型转换基础 PTR 到派生 PTR 保存在引用类中
c++ typecast base ptr to derived ptr held in a reference class
我正在尝试创建一个对象引用模板类,该模板类将保存类指针,并且除了尝试将强制基类 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,它将起作用,但这是不希望的。
我只是觉得我错过了一个操作员或其他东西。
谢谢。
像往常一样,我在发布后不久就找到了解决方案。
ObjRef<>类需要知道基类。 以下是新代码:
#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=%dn", d->baseValue);
b = d; //base does point to derived
func5((Derived)b); //cast from Base to Derived - works now!
printf("DerivedValue=%dn", d->derivedValue);
func6(d);
return 0;
}
更新:发布了一个新版本,该版本适用于任何级别的继承,但现在需要C++14(自动关键字(
更新 #2:现在使用单个 ObjRef 类(仍然需要 C++14(。 不幸的是,cl.exe 尚不支持"自动"模板参数:(
更新#3:添加了一些测试代码来证明它有效。
相关文章:
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- CLANG 编译器 说:变量"PTR"可能未初始化
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 如何检查QList中是否存在值
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 根据某个函数是否存在启用模板
- 如何将分支添加到已存在的TTree:ROOT
- 地图计数确实很重要,或者只是检查是否存在