2015-05-23 53 views
1

是否有任何使用friend重载一个已经声明的结构的构造函数与一个使用新定义的结构。例如,在下面的简单示例中,我想用struct B,而不是修改A.h来重载struct A构造函数。c + +重载构造函数与新类型/类和朋友

的main.cpp

#include "A.h" 
#include "B.h" 

int main() { 
    B x(2); 
    A y(B); 
}; 

struct A { 
    float a; 
    A(float); 
}; 

A::A(float f) { a=f; }; 

了Bh

struct B { 
    float b; 
    B(float); 
    B(A); 
}; 

B::B(float f) { b=f; }; 
B::B(A s)  { b=s.a; }; 

A::A(B s){ a=s.b; }; 
// ^^^----obviously error since A(B) is not declared, 
// but how can I make this work without changing A.h? 

我知道我可以在内与struct B;A(B);适当的位置解决问题。我也想出了一种使用模板的方法,但它不是一个优雅的解决方案。它需要修改A.h。由于我不想进入这里的原因,我不想采用这些技术。我想重载A :: A()构造函数而不修改A.h更重要的是,不假设#include "A.h"的位置是可控的。我认为这是朋友的职责,但我不知道是否/如何使它与构造函数一起工作。

+0

您是否在寻找[转换运算符](http://en.cppreference.com/w/cpp/language/cast_operator)? –

回答

5

您不能添加构造函数(或其他成员)到一个班级。但是,您可以在所涉及的其他类创建一个转换操作符:

class B { 
    // ... 
public: 
    explicit operator A() const { /* build an A object and return it */ } 
}; 
+0

你认为转换为'float'而不是'A'会更合适,所以OP的例子可以使用构造函数'A(float);'? – AndyG

+0

@AndyG:转换运算符可以完成构造'A'对象所需的任何操作,包括使用'float'构造函数构建'A',然后进行一些变化。如果需要非'explicit'构造函数,则直接转换为'A'还会减少某些转换序列中的转换次数。 –

+0

我从来没有见过这个转换运算符,我不知道它如何在功能上与构造函数有所不同,但是当我测试它时,它看起来正如我需要并符合我的约束一样工作。谢谢。 – codechimp

2

你不能重载不存在的东西。您也不能定义不存在的成员函数。但是,你可以写一个简单的函数来完成这些工作你:

A fromB(const B& s) { return A(s.b); } 

如果你被允许修改B,你可以给它一个转换操作符:

​​
+0

转换运算符不会这么做吗? – 0x499602D2

+0

@ 0x499602D2是的,这可能是一个选项。 – juanchopanza

+0

在满足我期望的功能和优雅方面,转换操作员是最好的选择。 – codechimp

0

如果你有超过B控制,并希望定义一个方法如何使AB您可以定义一个所谓的转换操作符:

#include <iostream> 
using namespace std; 

struct A 
{ 
    A(float val) : _val(val) {}; 
    float _val; 
}; 

struct B{ 
    operator A(){ // how to make A from B. 
     return A(2); 
    } 
}; 

int main() { 
    B b; 
    A a = b; 
    cout << a._val << '\n'; 
    return 0; 
} 

它基本上定义了一个演员操作符。