OlimilOops
OlimilOops

Reputation: 6797

struct constructor + function parameter

I am a C++ beginner. I have the following code, the reult is not what I expect. The question is why, resp. what is wrong. For sure, the most of you see it at the first glance.

struct Complex {
    float imag;
    float real;
    Complex( float i, float r) {
        imag = i;
        real = r;
    }
    Complex( float r) {
        Complex(0, r);
    }
    std::string str() {
        std::ostringstream s;
        s << "imag: " << imag << " | real: " << real << std::endl;
        return s.str();
    }
};
class Complexes {
    std::vector<Complex> * _complexes;
public:
    Complexes(){
        _complexes = new std::vector<Complex>;
    }
    void Add( Complex elem ) {
        _complexes->push_back( elem ); 
    }
    std::string str( int index ) {
        std::ostringstream oss;
        Complex c = _complexes->at(index);
        oss << c.str();
        return oss.str();
    }
};
int main(){
    Complexes * cs = new Complexes();
    //cs->Add(123.4f);
    cs->Add(Complex(123.4f));
    std::cout << cs->str(0); return 0; }

for now I am interested in the basics of c++ not in the complexnumber theory ;-) it would be nice if the "Add" function does also accept one real (without an extra overloading) instead of only a Complex-object is this possible?

many thanks in advance
Oops

Upvotes: 2

Views: 4479

Answers (5)

CB Bailey
CB Bailey

Reputation: 793017

Complex( float i, float r) {
    imag = i;
    real = r;
}
Complex( float r) {
    Complex(0, r);
}

This pair of constructors probably doesn't do what you intend.

The body of the second constructor constructs a nameless temporary Complex object which it then discards. The members real and imag are not initalized.

The simplest fix is this:

Complex( float r )
    : imag(0), real(r)
{
}

Currently C++ doesn't support delegating constructors so you can't call one conmstructor from another.

As Neil Butterworth comments, currently your Complexes class is probably made more complex by the use of a dynamically allocated vector of Complex. You would probably be better off with an object of type vector rather than a pointer. With a dynamically allocated vector you should provide a destrutor, copy construtor and copy assignment operator which you don't currently do in order to delete the vector and manage copying it at the appropriate points. Without doing this your class will (at best) leak memory.

Upvotes: 2

Danvil
Danvil

Reputation: 23031

You can also use the built-in class std::complex for complex numbers. It comes with arithmetics operators like +, -, *, ... and other functions. This will safe you some hassle in getting the math right.

Upvotes: 0

Danvil
Danvil

Reputation: 23031

Add the following method to the class Complexes:

class Complexes {
 // ...
 void Add( float real ) {
    _complexes->push_back( Complex(real) ); 
 }
 // ...
}

Upvotes: 0

anon
anon

Reputation:

Sure, just add:

void Add( float  elem ) {
    _complexes->push_back( elem ); 
}

C++ will call the constructor for you to create the Complex from the float. However, having many of these functions with the same name can lead to ambiguities, so don't go overboard.

I'd also observer that you don't need to create your vector of Complex dynamically - you should avoid dynamic creation of objects in C++ where possible. And the default choice for a real number datatype should be double, not float.

Upvotes: 0

Maciej Hehl
Maciej Hehl

Reputation: 7995

You can't call one constructor in the body of another one like that:

Complex( float r) {
        Complex(0, r);
    }

In C++ it creates a temporary object of class Complex which immediately gets destroyed.

You could use default parameters in the constructor or some private method that would be called by constructors

Upvotes: 4

Related Questions