使用一个对象上的两个构造函数

huangapple go评论50阅读模式
英文:

Using two constructors on one object

问题

你的代码中存在一个错误,这是因为在创建对象 newUser 后,你尝试再次调用构造函数来重新初始化它,但这是不允许的。构造函数只能在对象创建时调用一次,用于初始化对象的成员变量。

你可以使用成员函数来更新对象的属性,而不是尝试重新调用构造函数。例如,你可以添加一个名为 setMoneyInfo 的成员函数来更新 netIncometotalSavingstotalDebt 属性,如下所示:

class User
{
public:
    int UserAge;
    double netIncome, totalSavings, totalDebt;
    string UserName;

    // 构造函数用于初始化姓名和年龄
    User(string name, int age)
    {
        UserName = name;
        UserAge = age;
    }

    // 构造函数用于初始化金钱信息
    User(double income, double savings, double debt)
    {
        netIncome = income;
        totalSavings = savings;
        totalDebt = debt;
    }

    // 成员函数用于更新金钱信息
    void setMoneyInfo(double income, double savings, double debt)
    {
        netIncome = income;
        totalSavings = savings;
        totalDebt = debt;
    }
};

然后,在 main 函数中,你可以使用 setMoneyInfo 来更新 newUser 的金钱信息,而不是尝试再次调用构造函数:

// ...

User newUser(Name, Age); // 创建对象并初始化姓名和年龄

// ...

if (answer == "yes")
{
    cout << "What amount of debt must you pay? "; cin >> Debt;
}
else if (answer == "no")
{
    cout << "Great." << endl << endl;
    Debt = 0;
}

newUser.setMoneyInfo(Income, Savings, Debt); // 使用成员函数来更新金钱信息

这样,你就可以正确地更新 newUser 对象的属性,而不会再次调用构造函数。

英文:

I have a User class that has two constructors. When I create an object and use the two constructors, one of them gives me an error saying: no match for call to '(User) (double&, double&, double&)'

class User
{
public:
    int UserAge;
    double netIncome, totalSavings, totalDebt;
    string UserName;

    //Constructor for name and age
    User(string name, int age)
    {
        UserName = name;
        UserAge = age;
    }

    //Constructor for money info
    User(double income, double savings, double debt)
    {
        netIncome = income;
        totalSavings = savings;
        totalDebt = debt;
    }
};

Main:

int main()
{
    string Name, answer;
    int Age;
    double Income, Savings, Debt, Cost, goalCount;

    cout &lt;&lt; setw(82) &lt;&lt; &quot;--------------------------------------------------------------&quot; &lt;&lt; endl;
    cout &lt;&lt; setw(75) &lt;&lt; &quot;Hello and welcome to the RS Money Management App.&quot; &lt;&lt; endl &lt;&lt; endl;
    cout &lt;&lt; setw(76) &lt;&lt; &quot;Designed to help you be responsible with your money!&quot; &lt;&lt; endl;
    cout &lt;&lt; setw(82) &lt;&lt; &quot;--------------------------------------------------------------&quot; &lt;&lt; endl &lt;&lt; endl;

    cout &lt;&lt; setw(45) &lt;&lt; &quot;Please Enter Your Name: &quot;; cin &gt;&gt; Name;
    cout &lt;&lt; endl;
    cout &lt;&lt; setw(44) &lt;&lt; &quot;Please Enter Your Age: &quot;; cin &gt;&gt; Age;

    User newUser(Name, Age); //object created

    cout &lt;&lt; endl;

    system (&quot;CLS&quot;);

    cout &lt;&lt; &quot;------------------------------&quot; &lt;&lt; endl;
    cout &lt;&lt; setw(15) &lt;&lt; &quot;Welcome, &quot; &lt;&lt; newUser.UserName &lt;&lt; &quot;.&quot; &lt;&lt; endl;
    cout &lt;&lt; &quot;------------------------------&quot; &lt;&lt; endl;

    cout &lt;&lt; &quot;Let&#39;s start by asking you some simple questions.&quot; &lt;&lt; endl &lt;&lt; endl;

    Goals financialGoals[10];

    cout &lt;&lt; &quot;What is your current monthly net Income? &quot;; cin &gt;&gt; Income;

    cout &lt;&lt; &quot;How much are you currently saving? &quot;; cin &gt;&gt; Savings;

    cout &lt;&lt; &quot;Do you have Debts? &quot;; cin &gt;&gt; answer;


    if (answer == &quot;yes&quot;)
    {
        cout &lt;&lt; &quot;What amount of debt must you pay? &quot;; cin &gt;&gt; Debt;
    }
    else if (answer == &quot;no&quot;)
    {
        cout &lt;&lt; &quot;Great.&quot; &lt;&lt; endl &lt;&lt; endl;
        Debt = 0;
    }

    newUser(Income, Savings, Debt); //2nd constructor, where error is occuring

I am not sure what I am doing wrong. Am I not supposed to use two constructors on one object? Am I missing something?

答案1

得分: 2

你试图在一个已经存在的 User 对象上调用一个不存在的 operator(),并期望它调用第二个构造函数。这不是构造函数的工作方式。它们只能用于创建新对象,而不能用于修改对象。

因此,你需要:

  • 创建一个新的独立对象,例如:

    User newUser2(Income, Savings, Debt);
    
  • 否则,如果你的意图是修改一个已存在的对象,那么你将需要添加额外的方法来处理这个任务,例如:

    class User
    {
    public:
        int UserAge;
        double netIncome, totalSavings, totalDebt;
        string UserName;
    
        User()
        {
            setUserInfo("", 0);
            setMoneyInfo(0, 0, 0);
        }
    
        // 用于姓名和年龄的构造函数
        User(string name, int age)
        {
            setUserInfo(name, age);
            setMoneyInfo(0, 0, 0);
        }
    
        // 用于金钱信息的构造函数
        User(double income, double savings, double debt)
        {
            setUserInfo("", 0);
            setMoneyInfo(income, savings, debt);
        }
    
        void setUserInfo(string name, int age)
        {
            UserName = name;
            UserAge = age;
        }
    
        void setMoneyInfo(double income, double savings, double debt)
        {
            netIncome = income;
            totalSavings = savings;
            totalDebt = debt;
        }
    };
    

    然后你可以像这样操作:

    User newUser(Income, Savings, Debt);
    ...
    newUser.setUserInfo(Name, Age);
    
    User newUser(Name, Age);
    ...
    newUser.setMoneyInfo(Income, Savings, Debt);
    
    User newUser;
    ...
    newUser.setUserInfo(Name, Age);
    newUser.setMoneyInfo(Income, Savings, Debt);
    
英文:

You are trying to call a non-existent operator() on an existing User object, expecting it to call the 2nd constructor. That is not how constructors work. They can only be used to create new objects, not modify objects.

So, you need to either:

  • create a new, separate object, eg:

    User newUser2(Income, Savings, Debt);
    
  • Otherwise, if your intent is to modify an existing object, then you will have to add additional methods to handle that task, eg:

    class User
    {
    public:
        int UserAge;
        double netIncome, totalSavings, totalDebt;
        string UserName;
    
        User()
        {
            setUserInfo(&quot;&quot;, 0);
            setMoneyInfo(0, 0, 0);
        }
    
        //Constructor for name and age
        User(string name, int age)
        {
            setUserInfo(name, age);
            setMoneyInfo(0, 0, 0);
        }
    
        //Constructor for money info
        User(double income, double savings, double debt)
        {
            setUserInfo(&quot;&quot;, 0);
            setMoneyInfo(income, savings, debt);
        }
    
        void setUserInfo(string name, int age)
        {
            UserName = name;
            UserAge = age;
        }
    
        void setMoneyInfo(double income, double savings, double debt)
        {
            netIncome = income;
            totalSavings = savings;
            totalDebt = debt;
        }
    };
    

    Then you can do things like this:

    User newUser(Income, Savings, Debt);
    ...
    newUser.setUserInfo(Name, Age);
    
    User newUser(Name, Age);
    ...
    newUser.setMoneyInfo(Income, Savings, Debt);
    
    User newUser;
    ...
    newUser.setUserInfo(Name, Age);
    newUser.setMoneyInfo(Income, Savings, Debt);
    

答案2

得分: 0

不应该在一个对象上使用两个构造函数。

正确。

想象一下,你负责一个建筑队。你被派到一个空地上建造一座房子。你和你的队伍一起去,建造房子,然后返回家。完全是例行公事。不久之后,你被派到同样的地方,但现在不再是空地,要建造一座房子,而且要建在已经有房子的地方。你会怎么做?

你不能这样做,除非你先摧毁现有的房子。对于对象也是一样的道理。一旦构造完成,一个对象除非先被销毁,否则无法重新构造。你可以替换一个对象(例如使用赋值),但不能重新构造它。

如果你需要分阶段构建你的对象,可以使用构造函数加上一个设置器。如果你没有设置器,那么你无法分阶段构建对象。相反,你需要将数据保存在不同的变量中,直到你可以使用包含所有对象应该包含的数据的构造函数。

User newUser(Name, Age);
newUser.setIncome(Income);
newUser.setSavings(Savings);
newUser.setDebt(Debt);
// 或者使用组合设置器
newUser.setFinances(Income, Savings, Debt);

或者

User newUser(Name, Age, Income, Savings, Debt);

如果你的意图真的是要用一个新对象替换现有对象(失去名称和年龄信息),你可以定义一个赋值运算符,并将一个新对象分配给旧对象。这将会再次调用构造函数,但第二次是为一个新的(没有名称的临时)对象。在分配之后,新对象被销毁,但其数据的副本(或移动)被原始对象保留。最终结果类似于销毁原始对象并在同一位置构建替代品。

User newUser(Name, Age);
newUser = User(Income, Savings, Debt); // 名字和年龄信息会丢失

*注意:*这假设了赋值的传统语义,这并不是由语言强制执行的。

英文:

> Am I not supposed to use two constructors on one object?

Correct.

Picture this. You are in charge of a construction crew. You are sent to an empty field to build a house. You go with your crew, build the house, and return home. Fully routine. Shortly after that, you are sent to the same field -- no longer empty -- to build a house. In the same location as the house that is currently there. How would you do that?

You cannot. Not unless you destroy the existing house first. Same thing with objects. Once constructed, an object cannot be re-constructed unless it is destroyed first. You can replace an object (e.g. using assignment), but not re-construct it.

If you need to construct your object in stages, use a constructor plus a setter. If you don't have a setter, then you cannot contruct your object in stages. Instead, you would need to keep the data in separate variables until you can call a constructor with all the data an object is supposed to hold.

User newUser(Name, Age);
newUser.setIncome(Income);
newUser.setSavings(Savings);
newUser.setDebt(Debt);
// Or a combo setter like
newUser.setFinances(Income, Savings, Debt);

Or

User newUser(Name, Age, Income, Savings, Debt);

If your intent is really to replace the existing object with a new one (losing the name and age information), you could define an assignment operator and assign a new object to the old. This would call the constructor a second time, but the second time is for a new (unnamed, temporary) object. After the assignment, the new object is destroyed, but a copy (or move) of its data is retained by the original object. The end result is similar to destroying the original object and constructing a replacement in the same place.

User newUser(Name, Age);
newUser = User(Income, Savings, Debt); // Name and Age are lost

Caveat: This assumes the traditional semantics for assignment, which is not enforced by the language.

huangapple
  • 本文由 发表于 2023年2月10日 10:12:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406307.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定