自动将A *转换为B *

时间:2010-04-26 17:08:18

标签: c++ proxy smart-pointers conversion-operator

假设我有一个班级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的实例是在我无法控制的工厂中创建的)...

有可能吗?

感谢。

6 个答案:

答案 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);

}