аргумент' this ' имеет тип const, но функция не отмечена const

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

это файл заголовка с классом:

class Customer {

private:
    string PhoneNumber_;
    string Name_;
    string Address_;

public:
    string get_PhoneNumber() const {return PhoneNumber_;} // Accessor
    const void set_PhoneNumber(unsigned x) {PhoneNumber_ = x;} // Mutator

    string get_Name() const {return Name_;}
    const void set_Name(unsigned x) {Name_ = x;}

    string get_Address() const {return Address_;}
    const void set_Address(unsigned x)  {Address_ = x;}
};

// declare the CreateCustomer function prototype with default values
Customer* CreateCustomer(const string& id = BLANK, const string& name = BLANK, const string& address = BLANK);

Customer* CreateCustomer(const string& id, const string& name, const string& address) {
    Customer* temp = new Customer();

    temp->get_PhoneNumber() = id; // Due to the Accessors and Mutators PhoneNumber, Name and Address are now functions
    temp->get_Name() = name;
    temp->get_Address() = address;

    return temp;
}

и это ошибка, я получаю в основном.файл cpp:

cout << "nnDear ";
    cout << Charge[0].Holder.set_Name() << " (" << Charge[0].Holder.set_PhoneNumber() << ")";  //  DisplayCustomer(customer) ;

    cout << ",n" << Charge[0].Holder.set_Address() << "nn"

в основном, точное сообщение об ошибке:

функция-член 'set_Name' не всхожесть: 'этот' аргумент имеет тип 'const и Customer', но функция не является типом const

это происходит с set_PhoneNumber и set_Address, а также. Любая помощь будет очень признательна! Спасибо!

обновление: я заставил его работать. Спасибо всем за помощь!

4 ответов


Если вы хотите установить значение, используйте метод set. методы get предназначены только для получения переменных, а не для установки внутренних переменных класса (если они определены так, как вы это сделали).

правильное использование:

Customer* CreateCustomer(const string& id, const string& name, const string& address) {
    Customer* temp = new Customer();

    temp->set_PhoneNumber( id );
    temp->set_Name( name );
    temp->set_Address( address );

    return temp;
}

кроме того, вы должны изменить интерфейс вашего метода:

class Customer {

private:
    string PhoneNumber_;
    string Name_;
    string Address_;

public:
    string get_PhoneNumber() const {return PhoneNumber_;} // Accessor
    void set_PhoneNumber(const string& x) {PhoneNumber_ = x;} // Mutator

    string get_Name() const {return Name_;}
    void set_Name(const string& x) {Name_ = x;}

    string get_Address() const {return Address_;}
    void set_Address(const string& x)  {Address_ = x;}
};

Так как вы хотите установить строки, а не числа.

используя const string& как аргументы функции лучше, чем строка, чтобы не копировать строку при передаче ее как аргумент. Поскольку это ссылка const, вам не нужно бояться, что функция может манипулировать входом.


Эм. Я думаю, вы должны использовать get и set в обратный путь... В CreateCustomer вы должны использовать set функции и при печати Customer to stream-вы должны использовать get функции. И set функции получает string, а не unsigned.

и так, будет лучше использовать constructor, вместо set функции, а затем будет только get функции.


  1. вы должны использовать std:: в объявлении класса. См.почему "использование пространства имен std;" считается плохой практикой? на вопрос почему.

  2. код set_ методы take unsigned аргументов. Вы не можете назначить неподписанную строку как PhoneNumber_ = x;. Аргументы должны быть строками.

вам нужно будет изменить свои члены, как

std::string get_PhoneNumber() const { return PhoneNumber_; } // Accessor
const void set_PhoneNumber(std::string const & x) { PhoneNumber_ = x; } // Mutator
  1. когда вы пишете temp->get_PhoneNumber() = id; ваше намерение явно set значение PhoneNumber_, так почему же вы используете get_ способ? Просто используйте соответствующий set_ метод и написать temp->set_PhoneNumber(id);.

  2. обычно избегайте указателей на C++. Если вам действительно нужен указатель, используйте умный указатель, например std::unique_ptr или std::shared_ptr (если и только если требуется использовать простой указатель: используйте один).

  3. A 'blank' значение по умолчанию для std::string пустую строку типа

    std::string const & id = std::string{} кажется мне яснее.

  4. для создания объекта типа Customer С пустыми / пустыми строками членов вам не нужно делать больше, чем Customer customer_object; поскольку существует неявно объявленный конструктор по умолчанию, который использует std::string конструктор по умолчанию, который в любом случае приводит к пустому strign.

  5. обычно a конструктор используется для создания объекта в зависимости от некоторых значений аргументов.

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

Customer(const std::string& id = std::string{}, 
  const std::string& name = std::string{}, 
  const std::string& address = std::string{})
  : PhoneNumber_(id), Name_(name), Address_(address)
{ }

в свой класс. Смотрите другой пример списка инициализации класса C++.

посмотреть другое пример списка инициализации класса C++.

  1. ради инкапсуляции вы обычно хотите избежать использования'прямые' геттеры и сеттеры, раскрывающие структуру данных.

объявлено PhoneNumber_, Name_ и Address_ as string.
Но в методах сеттера вы проходите unsigned (int)

кроме того, вы изменили использование геттеров и сеттеров!

кроме того, возвращаемые типы сеттеров могут быть просто void, а не const void.