假设我有一个班级A
。我想将指针包装成一个小类B
,某种智能指针,约束条件B*
会自动转换为A*
,这样我就不会需要重写已使用A*
的代码。
因此我想修改B
以便以下编译...
struct A {
void foo() {}
};
template <class K>
struct B {
B(K* k) : _k(k) {}
//operator K*() {return _k;}
//K* operator->() {return _k;}
private:
K* _k;
};
void doSomething(A*) {}
void test() {
A a;
A* pointer_to_a (&a);
B<A> b (pointer_to_a);
//b->foo(); // I don't need those two...
//doSomething(b);
B<A>* pointer_to_b (&b);
// Following represents existing code I don't want to change...
pointer_to_b->foo(); // 'foo' : is not a member of 'B<K>'
doSomething(pointer_to_b); // 'doSomething' : cannot convert parameter 1 from 'B<K> *' to 'A *'
}
请注意,从B
继承的A
不是一个选项(A
的实例是在我无法控制的工厂中创建的)...
有可能吗?
感谢。
答案 0 :(得分:3)
pointer_to_b的类型是指针到B,这是一个你无法修改的类型;它由编译器实现。
你可以做( pointer_to_b) - &gt; foo(),它会做正确的事情(假设你有被覆盖的operator-&gt;())。但是,如果你将pointer_to_be传递给它,那就不会让其他代码做正确的事。
另外我要补充一点,你可以覆盖operator&amp;在B上返回A *,这可能会解决您的问题,具体取决于具体的用例。
答案 1 :(得分:2)
get()
中的函数boost::shared_ptr
怎么样?
template <class K>
struct B {
B(K* k) : _k(k) {}
K* get() { return _k;}
private:
K* _k;
};
然后您可以按如下方式使用它:
pointer_to_b->get()->foo();
doSomething(pointer_to_b->get());
答案 2 :(得分:0)
您在struct B
注释掉的运营商看起来应该让它按照您的意愿行事......为什么他们会被注释掉?当它们被取消注释时它不起作用,如果没有,你能发布错误吗?
答案 3 :(得分:0)
如果我回想一下shared_ptr
绕过这个问题的方式我认为你永远不会绕过shared_ptr*
,你会传递shared_ptr
个对象。这样operator->
就可以了,因为它是在对象上调用的,而不是指向对象的指针。我建议您传递B<A>
而不是B<A>*
。谁在乎包装类是否为指针,只要它表示指向A的指针就没关系。
答案 4 :(得分:0)
B继承自A 是一个选项,这个编译(至少VS 2008):
struct A {
void foo() {}
};
template <typename T>
struct B : T
{
B(const T& t) : T(t)
{}
};
void doSomething(A*) {}
void test() {
A a;
B<A> b (a);
B<A>* pointer_to_b (&b);
// Following represents existing code I don't want to change...
pointer_to_b->foo();
doSomething(pointer_to_b);
}
答案 5 :(得分:0)
这应该从我的角度来看
struct A {
void foo() {}
};
template <class K>
struct B {
B(K* k) : _k(k) {}
operator K*() {return _k;}
K* operator->() {return _k;}
private:
K* _k;
};
void doSomething(A*) {}
void test() {
A a;
A* pointer_to_a (&a);
B<A> pointer_to_b (pointer_to_a);
// Following represents existing code NOT CHANGED
pointer_to_b->foo();
doSomething(pointer_to_b);
}