c ++重载构造函数与新类型/类和朋友

时间:2015-05-23 21:26:25

标签: c++ constructor overloading friend

无论如何使用friend来重载已经声明的struct的构造函数,并使用新定义的结构。例如,在下面的简单示例中,我想要使用struct A BUT重载struct B构造函数而不修改A.h

的main.cpp

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

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

A.H

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

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

B.h

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?

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

3 个答案:

答案 0 :(得分:5)

您无法将构造函数(或其他成员)添加到类中。但是,您可以在所涉及的其他类中创建转换运算符:

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

答案 1 :(得分:2)

你不能超载那些不存在的东西。您也无法定义不存在的成员函数。但是你可以编写一个简单的函数来为你完成这项工作:

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

如果您允许修改B,则可以为其指定转换运算符:

struct B {
    explicit operator A() const { return A(b); }

    // as before
};

答案 2 :(得分:0)

如果您可以控制B并想要定义如何从A制作B,则可以定义所谓的转换运算符:

#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;
}

它基本上定义了一个强制转换操作符。