函数参数的类型转换

时间:2010-09-24 07:49:52

标签: c++ reference initialization

class A{
};

class B{
public:
    B();
    B(const &A);
};

void foo(A &a){

}

int main(){
   B b;
   foo(b); //error: invalid initialization of reference of type ‘A&’ from expression of type ‘B’
   return 0;
}

在上面的代码中,我有一个编译错误

错误:从“B”类型的表达式初始化“A&”类型的引用无效

错误可以通过函数重载foo()来解决。但是,您对我如何解决问题有任何其他建议吗?

function foo(A& a)不使用参数“a”作为输入。参数“a”只是函数foo(A& a)的输出。

感谢。

4 个答案:

答案 0 :(得分:3)

有很多选择......很难知道在不理解你的程序尝试的情况下推荐什么。我们对A和B之间的逻辑关系给出的小小见解是:

  • 只有B的构造函数中的一个需要对A对象的非const引用
  • foo()旨在使用A或B

这意味着指向A的指针可能会被保存在B中,但是问题是:foo()应该与所有B一起工作(如果没有在构造中提供,可能使用默认构造的A)或者仅使用构造的那些参考A?

设计选项包括:

  • 从A派生B(但是你的默认构造函数表明B可以存在但没有被“绑定”到A)
  • A& get_A()和/或const A& get_A() const成员添加到class B,然后致电foo(b.get_A());
    • 使用operator A&()operator const A&() const
    • 隐式执行此操作
    • 如果A是可选的
    • ,您可能更喜欢A* get_A()
  • template <class A_or_B> foo(A_or_B&)如果A和B为foo提供正确的成员/语义
  • 重载foo,为每种类型提供不同的实现

探索性代码:

#include <iostream>

struct A
{
    int n_;
};

void foo(A& a)
{
   a.n_++;
}


struct B
{
    // e.g. B() : p_a_(new A), owner_(true) { } ?
    //      ~B() { if (owner_) delete p_a_; }
    B(A& a) : p_a_(&a) { }

    operator A&() { return *p_a_; }

    A* p_a_;
};

int main()
{
    A a;
    a.n_ = 2;
    B b(a);
    foo(a);
    foo(b);
    std::cout << a.n_ << '\n';
}

答案 1 :(得分:0)

问题是您正在尝试将对象B隐式转换为对象A.考虑到这些是分离类,编译器将无法执行此操作。虽然可以明确地将对象B的指针或引用转换为* /&amp;对象A,这会混淆编译器,这是一个非常糟糕的主意。

就像你要求编译器将苹果转换为橙色,无法完成。如果B是A的子类,那么这是完全可能的。但是,如果这两个类没有任何共同点或没有共同点,那么你不能简单地将其作为一种解决方法。但是,如果他们这样做,并且你有几个相关的类,则创建一个基类(包含共享方法),并使所有这些类派生自它。

同样,请不要执行(A*)(&b)之类的操作,因为如果您不知道foo()参数中实际获得的是什么类,这将导致运行时问题(同样,除非B来自A)。

当然,最好的做法是重载Foo()。

编辑:你看,你可以在B的构造函数中从A转换为B.但是你需要A并且有一个B,所以需要REVERSE转换。这就是您当前代码不起作用的原因。

答案 2 :(得分:0)

你真的想要A和B作为不相关的类吗?如果A和B类共享是一个关系,那么最好从A派生B.

class B : public A

然后foo(b)与foo(A&amp; a)作为签名将导致对象切片。

答案 3 :(得分:0)

最简单的方法..如果你愿意在对象A中分配对象B.你需要看看它们是否兼容的关系。

从我的下一次尝试进行编译:

class A{ 

}; 

class B: public A{ 
public: 
    B(){
    }
    B(const A&){
    }
}; 

void foo(A &a){ 

}

希望它值得。