【问题标题】:How do I pass a TForm (this) generically?我如何一般地传递​​ TForm (this)?
【发布时间】:2019-08-12 15:51:49
【问题描述】:

我有两个几乎相同的表单(Form4 和 Form5),它们有几个共同的项目,但处理不同的数据。 我正在尝试编写一个可以采用这两种形式的辅助函数。

两种形式都是动态创建的。

到目前为止,我能够编写处理来自 Form4 [Process(TForm4 *F)] 的数据的函数。我不能从 Form5 做同样的事情,因为辅助函数是特定于 TForm4 的。

来自 Form4

 Edit1Exit(Tobject *Sender){     
   Process(this);
 }

来自Form5

 Edit1Exit(Tobject *Sender){     
   Process(this);
 }

 Process(TForm4 *F){
  // Do something like F->BitBtn1->Visible=false;
  }

问题是 Process( ) 是为 TForm4 编写的,所以它不会接受 TForm5。

如何声明 Process() 以便它采用任何一种形式。

【问题讨论】:

  • 听起来像是模板函数的工作(或者,如果你愿意,重载函数)..
  • 为什么不从基类中派生 TForm4 和 TForm5 并将基类作为参数传递给您的常用方法?

标签: c++ c++builder-10.2-tokyo


【解决方案1】:

一般来说,您将有三种选择:

  1. 为每个版本编写显式重载,并复制代码。即,
void Process(TForm4* F) {
   /// do things
}

void Process(TForm5* F) {
   /// do things
}

  1. 从声明虚拟接口的公共基类派生,即,
class TFormBase {
    // common virtual interface, and a virtual destructor
};

class TForm4 : public TFormBase {
    // implementation of the interface + data members
};

class TForm5 : public TFormBase {
    // implementation of the interface + data members
};

void Process(TFormBase* F) {
    // interact with F via the virtual interface
}

  1. 使用模板(但在这种情况下,函数的实现必须在使用它的地方可以访问;通常这意味着它必须存在于头文件或可以直接包含的文件中),即,
template<typename T>
void Process(T* F) {
    // interact with the classes; assumes a common interface
}

为简单起见,我省略了很多细节,但这应该可以帮助您入门。

【讨论】:

  • 感谢您的帮助。我可以做选项 1 和 2,但我不认为它们比将代码留在表单中更好。我以前没有使用过模板,所以我没有想到它们。看起来这会做我想要的。
  • 第二个选项是面向对象编程的标准模式,它会是更“规范”和可扩展的方式(即,如果您需要创建 TForm3 或 TForm6 或更改在维护界面的同时,他们中的一个人的行为略有不同,这就是要走的路)。所以我不会立即打折:) 使用模板进行元编程也不是一个坏方法,但公开实现以及代码为不同类型重复编译的事实对于某些应用程序来说可能是不可行的。
猜你喜欢
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 2016-12-11
  • 1970-01-01
  • 2012-02-28
相关资源
最近更新 更多