codechimp
codechimp

Reputation: 1557

c++ overloading constructor with new type/class and friend

Is there anyway to use friend to overload an already declared struct's constructor with one that uses newly defined structure. For example, in the simply example below, I want to overload struct A constructor with a one using struct B, BUT without modifying 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?

I know I can solve the problem with the appropriate placement of struct B; and A(B); within the A.h. I also figured out one method of using template, but it was not an elegant solution. And it required modification of A.h. For reasons I don't want to get in to here, I don't want to employ either of these technique. I would like to overload A::A() constructor WITHOUT modifying A.h and more importantly, without assuming that placement of #include "A.h" is controllable. I think this is what friend is for, but I don't know if/how to make it work with constructors.

Upvotes: 1

Views: 210

Answers (3)

juanchopanza
juanchopanza

Reputation: 227468

You can't overload something that doesn't exist. You can't define non existing member functions either. But you can write a simple function to do the work for you:

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

If you are allowed to modify B, you can give it a conversion operator:

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

    // as before
};

Upvotes: 2

luk32
luk32

Reputation: 16080

If you have a control over B and want to define a way how to make A from B you can define a so called conversion operator:

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

It basically defines a cast operator.

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153955

You can't add constructors (or other members) to a class. However, you can create a conversion operator in the other class involved:

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

Upvotes: 5

Related Questions