Мне было интересно, можно ли переопределить метод объекта бывший:
class Object{
public:
void Foo(){
//do something
}
};
Object* obj = new Object();
obj->Foo() {
//do something else
}
Я пытался использовать функциональную переменную, но она все равно не работает.
Пожалуйста, помогите, я чувствую, что вот-вот потеряю мозги из-за этой проблемы.
Кажется, вы просите о функциональной переменной, поэтому я опубликую код, который не работает, чтобы люди могли вам в этом помочь.
Нет, вам придется объявить подкласс и вместо этого создать экземпляр объекта подкласса.
Совершенно не связанное с этим тактическое примечание: здесь нет необходимости использовать new, чтобы получить экземпляр Object, и это, вероятно, навредит вам несколькими способами. Object obj; сделает все, что вам нужно, без необходимости дорогостоящего динамического распределения и необходимости вручную управлять временем жизни экземпляра. Это сбивает с толку многих новых программистов, которые переходят на C++ из языка, где new — единственный способ получить экземпляр объекта. В C++ new — это один из последних инструментов, к которым вам следует обратиться, и его лучше всего использовать для написания низкоуровневого служебного кода.
@Jarod42 спасибо за идею, она действительно работает так, как я хотел, чтобы она работала сейчас.
@user4581301 user4581301 Мне нужно вызвать new, потому что я хочу сохранить его как указатель, чтобы я мог передавать его другим функциям, а что нет, но спасибо за предложение
newпока не обязательно. Вы можете передать указатель на любой объект с помощью оператора адреса. например: myfunc(&obj); Примечание: избегайте использования указателя, если вместо него можно использовать ссылку. Передать плохую ссылку труднее, чем передать плохой указатель.





Как упомянул @Jarod42 в комментариях, я бы добавил участника std::function или другого вызываемого участника. Как пример (Годболт)
#include <functional>
#include <iostream>
#include <utility>
class Object {
public:
Object(std::function<int(int)> do_work) : do_work_(std::move(do_work)) {}
int DoWork(int i) { return do_work_(i); }
private:
std::function<int(int)> do_work_;
};
int main() {
Object obj1{[](int i){ return i + 1;}};
std::cout << obj1.DoWork(1) << '\n';
Object obj2{[](int i){ return i - 1;}};
std::cout << obj2.DoWork(1) << '\n';
}
Вы можете видеть, что DoWork вызывает вызываемый объект, и каждый экземпляр класса Object может свободно определять, что это за работа.
Нет, члены функции не являются данными в C++, поэтому их нельзя изменять отдельно для каждого объекта. Нет obj->Foo(); есть только Object::Foo(), который получает скрытый параметр this, указывающий на *obj.
Если вам нужно разрешить пользователю вашего класса настраивать поведение класса, у вас есть два основных варианта:
virtual и позвольте пользователям создавать новый дочерний класс из вашего класса:class Object {
public:
virtual void Foo() {
// do something
}
};
class DerivedObject {
public:
void Foo() override {
// Do something else
}
};
int main() {
Object* obj = new DerivedObject();
obj->Foo(); // will call DerivedObject::Foo()
}
Это немного усложняет обработку объекта, поскольку теперь вам нужно всегда передавать указатели и ссылки, что может потребовать динамического выделения, когда статически типизированный объект этого не требует. Преимущество этого метода заключается в том, что пользователи могут добавлять к объекту дополнительное состояние для работы своих пользовательских функций. Например, DerivedObject может иметь дополнительные элементы данных, к которым DerivedObject::Foo может получить доступ для выполнения своей работы.
class Object {
public:
Object(std::function<void(Object*)> foo)
: foo_{std::move(foo)}
{}
Object()
: foo_{[](Object* self) { /* do something */ }}
{}
void Foo() {
foo_(this);
}
private:
std::function<void(Object*)> foo_;
};
int main() {
Object o{[](Object* self) {
// do something else
}};
o.Foo();
}
Это упрощает обработку Object объектов, поскольку нормальная семантика значений по-прежнему сохраняется. Вы можете копировать, назначать, передавать по значению и т. д. без потери какой-либо информации об объекте. Однако по умолчанию член функционального объекта не имеет доступа к самому объекту. Вам нужно будет либо захватить ссылку или указатель на объект, либо передать его объекту функции каждый раз, когда он вызывается. В примере я сделал последнее, так как первое обычно не работает при копировании объектов.
Вместо этого у вас есть участник
std::function?