c++仅为特定实例重写函数
c++ overriding a function only for a specific instance
我想知道是否有一种方法可以只覆盖特定实例的函数。例如
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
有办法做到这一点吗?
我认为虚拟函数正是你想要的,有了虚拟函数,同一类型的不同实例可以有不同的函数,但你需要继承基类。例如
class A
{
public:
...
virtual void update()
{
std::cout << "Class An";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class Bn";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class Cn";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
上面代码中的每个实例都将绑定不同的更新函数。
此外,您也可以使用函数指针来实现您的需求,但不建议这样做。例如
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update An";
}
void b_update()
{
std::cout << "update Bn";
}
void c_update()
{
std::cout << "update Cn";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
希望有帮助!
在类中保持一个function
。
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
您可能已经注意到,类的右大括号后面通常跟有分号,而函数、while
循环等的右大引号后面则没有。这是有原因的,这与C中struct
的一个特性有关。因为class
几乎与struct
相同,所以C++类也存在这个特性。
基本上,C中的struct
可以声明一个命名实例,而不是(或)一个命名的"类型"(因为C中的struct
类型本身不是有效的类型名,所以使用引号)。因此,C++类可以做同样的事情,尽管AFAIK可能对该类的其他功能有严重的限制
我现在无法检查,当然我也不记得使用过它,但这可能意味着你可以声明一个从基类继承的命名类实例,而不给它一个类名。仍然会有一个派生类型,但它将是匿名的。
如果有效,它应该看起来像。。。
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
就我个人而言,即使这是有效的,我也会避免使用它,原因有很多。例如,缺少类名意味着不可能单独定义成员函数。这意味着整个类的声明和定义必须放在你想要声明实例的地方——在函数的中间,甚至在全局变量的列表中,会有很多混乱。
如果没有类名,可能就没有办法声明构造函数或析构函数。如果你有来自基类的非默认构造函数,那么AFAIK就没有办法用它来指定构造函数参数。
正如我所说,我还没有检查过这一点——这种语法很可能是非法的,也很丑陋。
针对每个实例的不同行为,一些更实用的方法包括。。。
使用依赖项注入-例如,为行为的某个部分提供函数指针或类实例(或lambda)作为构造函数参数。
使用模板类有效地编译时依赖项注入,依赖项作为模板的函数参数提供。
我认为最好告诉我们为什么需要为特定实例重写函数
但这里有另一种方法:战略模式
你的班级需要一个能代表某些行为的成员。因此,您正在创建一些抽象类,它将成为不同行为的接口,然后您将在该抽象类的子类中实现不同的行为。因此,您可以在任何时间为任何对象选择这些行为。
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
您可以使用本地类,但就我个人而言,我认为另一个答案中提到的"类中保持函数"方法更好。只有当doFunc
必须访问基类的内部时,我才建议使用以下方法,这在成员变量中的函数中是不可能的:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
从设计模式的角度来看,"局部类"方法实现了模板方法模式,而"在成员变量中保持函数(al)"方法则反映了<em]策略模式>
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 从C++实例化QML
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 我收到以下错误:抛出'std::bad_alloc'实例后终止调用
- 建议在运行时将带有类实例的列表从c++导入qml
- 在 C++ 中用派生类型重写成员函数
- 只有当类重写方法时,在动态加载的共享库中实例化的类才会丢失XCode 4.3/4.4 typeinfo
- c++仅为特定实例重写函数
- 如何实例化派生类而不必重写代码
- 为什么子类的非重写实例方法中的"this"类型是父类型?
- 用std::initializer_list中的实例重写