2010-04-24 2 views
2

Я начинающий C++. У меня есть следующий код, результат не тот, который я ожидаю. Вопрос в том, почему, соотв. что не так. Конечно, большинство из вас видит это на первый взгляд.struct constructor + function parameter

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

сейчас я заинтересован в основах C++ не в теории ComplexNumber ;-) было бы неплохо, если бы «Добавить» функция не также принимает один реальный (без дополнительной перегрузки), а не только Комплексный объект - это возможно?

много спасибо заранее
Упс

+1

* huih *, должен сказать, этот форум настолько невероятно быстр, очень велик. Все вы были очень полезны! еще раз спасибо. – OlimilOops

+0

Не забудьте принять ответы на ваши более старые вопросы. –

+0

Обратите внимание, что это общепринятое соглашение для классов с комплексным числом, чтобы сначала назвать действительную часть, а затем мнимую часть. –

ответ

4

Вы не можете вызвать один конструктор в теле другого подобного:

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

В C++ это создает временный объект класса Complex, который сразу же разрушается.

Вы можете использовать параметры по умолчанию в конструкторе или каким-либо частным способом, который будет называться конструкторами

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

Эта пара конструкторов, вероятно, не делать то, что вы собираетесь.

Тело второго конструктора создает неназванный временный сложный объект, который затем отбрасывается. Члены real и imag не инициализированы.

Самым простым способом исправить это:

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

В настоящее время C++ не поддерживает делегировании конструкторов, так что вы не можете назвать одну conmstructor от другого.

Как замечает Нейл Баттерворт, в настоящее время ваш класс Complexes, вероятно, усложняется с помощью динамически распределенного vectorComplex. Вероятно, вам лучше будет объект с типом vector, а не указатель. С помощью динамически выделенного вектора вы должны предоставить оператор destrutor, copy construtor и copy, который вы в настоящее время не выполняете, чтобы вектор delete и управлять копированием его в соответствующих точках. Без этого ваш класс будет (в лучшем случае) утечкой памяти.

0

Конечно, просто добавьте:

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

C++ будет вызывать конструктор для вас, чтобы создать комплекс из поплавок. Однако наличие многих из этих функций с тем же именем может привести к двусмысленности, поэтому не переходите за борт.

Я также наблюдал, что вам не нужно создавать свой вектор Сложности динамически - вы должны избегать динамического создания объектов на C++, где это возможно. И выбор по умолчанию для реального типа данных должен быть двойным, а не плавающим.

0

Добавьте следующий метод к классу комплексов:

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

Вы также можете использовать встроенный класс std::complex для комплексных чисел. Он поставляется с операторами арифметики, такими как +, -, *, ... и другими функциями. Это сбережет вас от хлопот в правильной математике.