2

ここでノブ。本のエクササイズをしながら疑問を抱くこと。

疑問は次のとおりです。 メソッドの引数としてconst std::string *を使用すると、コンパイラから次のエラーが返されるのはなぜですか: 'BankAccount::define(const char [11], const char [11], int)'クライアントで?

メソッドのプロトタイプと定義を交換してconst std::string &を引数として受け入れる場合(コンストラクターで行ったように)、コンパイラーにとっては問題ありません。

クライアント:

// usebacnt.cpp --

#include "BankAccount.h"
#include <iostream>

int main()
{
    BankAccount john;
    BankAccount mary("Mary Wilkinson", "5000000000"); // balance set to 0 because of default argument
    john.display();
    mary.display();
    john.define("John Smith", "4000000000", 26); // error line
    mary.deposit(1000.50);
    john.withdraw(25);
    john.display();
    mary.display();
    std::cin.get();
    return 0;
}

クラス宣言:

// BankAccount.h -- Header file for project Exercise 10.1

#ifndef BANKACCOUNT_H_
#define BANKACCOUNT_H_

#include <string>

class BankAccount
{
private:
    std::string fullName;
    std::string accountNumber;
    double balance;
public:
    BankAccount(); // default constructor
    BankAccount(const std::string &fN, const std::string &aN, double b = 0.0); // constructor with a default argument
    void display() const;
    void deposit(double amount);
    void withdraw(double amount);
    void define(const std::string *pfN, const std::string *paN, double b);
};

#endif

クラスの実装:

// methods.cpp -- Compile alongside usebacnt.cpp

#include "BankAccount.h"
#include <iostream>

void BankAccount::display() const
{
    using std::cout;
    using std::ios_base;
    ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield); // formatting output and saving original
    cout.precision(2);
    cout << "Full Name: " << fullName << '\n';
    cout << "Account Number: " << accountNumber << '\n';
    cout << "Balance: " << balance << "\n\n";
    cout.setf(orig);
}

void BankAccount::deposit(double amount)
{
    if (amount < 0)
    {
        std::cout << "You can't deposit a negative number! Amount set to zero.";
        amount = 0;
    }
    balance += amount;
}

void BankAccount::withdraw(double amount)
{
    if (amount < 0)
    {
        std::cout << "You can't withdraw a negative number! Amount set to zero.";
        amount = 0;
    }
    if (balance < amount)
    {
        std::cout << "You can't withdraw more money than you have. Amount set to zero.";
        amount = 0;
    }
    balance -= amount;
}

void BankAccount::define(const std::string *pfN, const std::string *paN, double b)
{
    fullName = *fN;
    accountNumber = *aN;
    balance = b;
}

// constructors
BankAccount::BankAccount() // default constructor
{
    fullName = "empty";
    accountNumber = "empty";
    balance = 0.0;
}

BankAccount::BankAccount(const std::string &fN, const std::string &aN, double b) // constructor with default argument
{
    fullName = fN;
    accountNumber = aN;
    balance = b;
}

コンパイラはリテラルを文字列オブジェクトとして解釈すべきではありませんか (参照の場合と同様)。したがって、それがポインターであると言う場合、文字列のアドレス (最初の要素) を渡す必要があります。

何か助けはありますか?

4

1 に答える 1

4

コンパイラはリテラルを文字列オブジェクトとして解釈すべきではありませんか (参照の場合と同様)。

いいえ。ポインターは参照ではありません。彼らがそうであるとあなたに言う人を平手打ちします。

結局のところ、これstd::stringは文字列リテラルではありません。したがって、 を受け取る関数に文字列リテラルを渡す場合、リテラルの内容を保持std::stringする一時的なstd::stringを作成する必要があります。これは、 の変換コンストラクターで行われstd::stringます。

Aconst&は一時的なものから初期化できるため、変換コンストラクターが魔法を働かせることができます。Aconst*はポインターである必要があり、一時オブジェクトへのポインターを取得することは想定されていません。したがって、const*変換コンストラクターから作成された一時によって魔法のように埋められることはありません。

const std::string &ポインターの代わりに aを使用する必要があります。または、std::stringC++11 移動コンストラクターが使用可能な場合は値。

于 2012-08-10T15:59:51.437 に答える