C++:构造函数问题

lin*_*c88 5 c++ constructor

我正在尝试自学C++,而且我正在进行有关构造函数的基本练习.我有一个程序出乎意料地行为:

Fraction.h:

#include <iostream>

#ifndef FRACTION_H
#define FRACTION_H

using namespace std;

class Fraction
{
private:
    int num;
    int denom;
    static int gcd(int a, int b);
    void reduce();
public:
    Fraction(int n=0, int d=1);
    Fraction(Fraction& f);
    ~Fraction();

    Fraction& operator=(const Fraction& f);

    friend Fraction operator+(const Fraction& f1, const Fraction& f2);

    friend ostream& operator<<(ostream& out, const Fraction& f);
};

#endif // FRACTION_H
Run Code Online (Sandbox Code Playgroud)

Fraction.cpp(省略了一些实现):

#include "../include/Fraction.h"

#include <cassert>
#include <iostream>

using namespace std;

int Fraction::gcd(int a, int b) {
    // implementation omitted
}

void Fraction::reduce() {
    // implementation omitted
    // this just reduces fractions to lowest terms, like 3/6 to 1/2
}

Fraction::Fraction(int n, int d) {
    cout << "new fraction, n=" << n << ", d=" << d << endl;
    assert(d != 0);
    if (d < 0) {
        num = -n;
        denom = -d;
    } else {
        num = n;
        denom = d;
    }
    reduce();
}

Fraction::Fraction(Fraction& f) {
    cout << "copy fraction " << f << " at " << &f << endl;
    num = f.num;
    denom = f.denom;
}

Fraction::~Fraction() {
}

Fraction& Fraction::operator=(const Fraction& f) {
    cout << "assign fraction to " << f << " at " << &f << endl;
    if (this == &f)
        return *this;
    num = f.num;
    denom = f.denom;
    return *this;
}

Fraction operator+(const Fraction& f1, const Fraction& f2) {
    cout << "adding " << f1 << " and " << f2 << endl;
    return Fraction(f1.num * f2.denom + f2.num * f1.denom,
                    f1.denom * f2.denom);
}

ostream& operator<<(ostream& out, const Fraction& f) {
    out << f.num << "/" << f.denom;
    return out;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中:

#include "include/Fraction.h"

#include <iostream>

using namespace std;

int main()
{
    Fraction f1(1, 3);
    Fraction f2(1, 2);
    cout << f1 << endl;
    cout << f2 << endl;
    cout << (f1 + f2) << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,前两个打印语句输出1/3并按1/2预期输出,但第三个打印语句打印0/1而不是5/6.从我的调试语句,我通过Fraction(int, int)构造函数创建5/6 ,但由于某种原因,它然后用0/1调用.当我删除复制构造函数时,代码打印出来5/6.这里发生了什么,如何在不删除复制构造函数的情况下修复它?

Set*_*gie 7

复制构造函数的签名应该是

Fraction(const Fraction&);
Run Code Online (Sandbox Code Playgroud)

Fraction(Fraction&);
Run Code Online (Sandbox Code Playgroud)

当你这样做时return Fraction(...);,编译器必须调用,Fraction(const Fraction&)因为返回的分数是临时的,但由于你没有定义它,你的编译器会发生奇怪的事情.您的编译器表现得非常奇怪,并允许您以某种方式使用默认构造函数,何时应该发出错误.在gcc上按原样编译代码不起作用,你必须进行我提到的修改,并且应该修复它.

此外,您的编译器未在该函数上使用RVO的事实暗示您使用的是非常旧的和/或糟糕的编译器.

  • 嗨@ user1320895,我发现你是StackOverflow的新手.由于您确定这是正确的答案,请确保按此答案上的"接受"复选标记,即此处的礼仪.(因为我没有发布实际答案,我被允许成为提醒你的人:-)). (3认同)