巴解组织。应用问题 - 页 4

 
Yedelkin:

问题。在父类中声明了具有一定参数和类型的虚函数 后,是否可以在子类中改变相应虚函数的参数数量和类型?

一方面,《参考手册》指出,"一个虚拟函数可以在派生类中被替换 为虚拟函数调用哪个 函数定义 选择 动态的(在运行时)一个典型的情况是当一个基类包含和派生类有他们自己的该函数的版本时"。另一方面,《参考手册》中给出的例子是指虚拟函数具有不同的函数定义体而 不是函数定义 的情况。

在我的记忆中,这是有可能的。但你必须对参数的类型和数量绝对谨慎。

你还必须注意传递的值的类型和默认值。

为了简单起见,这里有一些例子。

这个变体将起到作用。

boll MyFunction(int Param);
boll MyFunction(int Param1,int Param2);

这个没有(或者说,也许它会工作,但有一些错误和某些保留)。

//Ели второй параметр будет упущен, то компилятор может и не "понять" смысла всего задуманного
boll MyFunction(int Param);
boll MyFunction(int Param1,int Param2 = 0);
//Так тоже может не прокатить по причине совпадения типов у второго параметра
boll MyFunction(int Param1,color Param2);
boll MyFunction(int Param1,int Param2);

当你重新加载类中的方法时,会发生完全相同的事情。

 
mql5:
只有定义的精确拷贝,除了默认设置(默认值可能不同,但最好不要使用这个)。
你的意思是 "只有定义 的精确拷贝 "吗?毕竟,函数定义 包括头和主体。例子中的身体肯定是不同的。
 

有趣的是,按照我的理解,函数虚拟化和函数重载是略有不同的事情。而mql5 说,在函数虚拟化中,应该有一个函数头的硬拷贝(我不考虑默认参数)。

 
Yedelkin:

有趣的是,按照我的理解,函数虚拟化和函数重载是有点不同的事情。而mql5 说,在函数虚拟化中,应该有一个函数头的硬拷贝(我没有考虑默认参数)。

> 问题。在父类中声明了具有一定参数及其类型的虚拟函数 后,是否可以在子类中改变相应虚拟函数的参数数量和类型?

如果我理解正确,子代必须重载祖代的功能。

坦率地说,我不记得在虚拟中做过这样的事情(我想我做过),但关于超载的说法是真的--我自己也犯过一次这样的错误。

PS

如果一切操作正确,按照我的理解,参数的数量既可以增加也可以减少。困难在于,如果参数的数量保持不变,但它们的类型发生了变化......。

 

总之,我已经勾勒出这个例子。

class C_A             //родительский класс
{
 public:
 virtual double function(double a1, double a2, double a3) { return; }
}
class C_B : public C_A
{
 public:
 virtual double function(double a1, double a2, double a3) { return(a1);   }
}
class C_C : public C_A
{
 public:      
 virtual double function(double a1, double a2, double a3) { return(a2);   }
        double function(double a1, double a2)           { return(a1+a2); }
}
//где-то в программе объявляем указатель
C_A  *pointer;
int random=rand()%2;
   switch(random)
     {
      case 0: pointer=new C_B; break;
      case 1: pointer=new C_C; break;
     }

//вызываем виртуальный метод
   if(pointer!=NULL)
     {
      pointer.function(a1,a2,a3);
     }

事实证明,无论一个函数方法在C_C类中是否被重载,一个虚拟函数 只能用三个参数调用--pointer.function(a1,a2,a3)。相应地,在调用虚拟函数时,程序将永远无法进入C_C类的双参数方法。对吗?

 
Yedelkin:

总之,我已经勾勒出这个例子。

事实证明,无论一个函数方法在C_C类中是否被重载,一个虚拟函数 只能用三个参数调用--pointer.function(a1,a2,a3)。相应地,在调用虚拟函数时,程序将永远无法进入C_C类的双参数方法。对吗?

通过插入带有__FUNCTION__宏的构造函数和析构函数打印,分析程序的作用,这将是非常有用的。

我还想补充一点,声明一个指向基类的指针,你就通过基类构建了一条通往子类的 "隧道"。因此,编译器在以这种方式调用子代时,将只看到基类中声明的函数。如果你(甚至在同一个程序中)直接声明一个子代对象,所有的函数都将在其中可用。

class C_A             //родительский класс
{
 public:
 virtual double function(double a1, double a2, double a3) { return; }
}
class C_B : public C_A
{
 public:
 virtual double function(double a1, double a2, double a3) { return(a1);   }
}
class C_C : public C_A
{
 public:      
 virtual double function(double a1, double a2, double a3) { return(a2);   }
        double function(double a1, double a2)           { return(a1+a2); }
}
//где-то в программе объявляем указатель
C_A  *pointer;
int random=rand()%2;
   switch(random)
     {
      case 0: pointer=new C_B; break;
      case 1: pointer=new C_C; break;
//вызываем виртуальный метод
   if(pointer!=NULL)
     {
      pointer.function(a1,a2,a3);
     }
C_С  *new_pointer=new C_C;
      new_pointer.function(a1,a2);
 
Yedelkin:

总之,我已经勾勒出这个例子。

事实证明,无论一个函数方法在C_C类中是否被重载,一个虚拟函数 只能用三个参数调用--pointer.function(a1,a2,a3)。相应地,在调用虚拟函数时,程序将永远无法进入C_C类的双参数方法。对吗?

根据我自己的经验,我可以建议你用以下方式打包代码

double function(double a1, double a2)            {return(a1+a2);}
double function(double a1, double a2, double a3) {return(a2);}

而你可以看到附件中的文件作为一个例子和娱乐。

我不想为指针和new而烦恼,所以我简单地将工作类声明为一个变量。

专家顾问在相等的时间间隔内产生一个随机数0/1,并根据结果执行两个功能之一:市场买入/市场卖出。


如果你愿意,你可以这样做

bool MarketBuy(string SymbolTitle,double LotSize,double TP = 0.0,double SL = 0.0);
bool MarketSell(string SymbolTitle,double LotSize,double TP = 0.0,double SL = 0.0);

但在这种情况下,可能会出现一个错误,因为它与

bool MarketBuy(string SymbolTitle,double LotSize);
bool MarketSell(string SymbolTitle,double LotSize);


PS

我是用手做的,这就是为什么可能有一些不准确的地方。

但原则上可以理解其基本思想。

附加的文件:
Forum.mq5  18 kb
 

非常感谢您 的宝贵意见和指导!我一定会使用它们,但我希望我有足够的时间进行理论和实践。

Interesting:

根据我自己的经验,我可以建议这样完成代码

double function(double a1, double a2)            {return(a1+a2);}
double function(double a1, double a2, double a3) {return(a2);}
为什么这样做?陷阱是什么?
 
Yedelkin:

为什么会这样呢?陷阱是什么?

我想,过去在这方面有一个问题。但我现在不记得是哪些人了。

总之,我已经习惯了。

当然,通常情况下是没有区别的,至少在我的例子中,我试着交换了位置,结果都成功了......。

 
Interesting:

我想,过去在这方面有一个问题。但我现在不记得是哪些人了。

好吧,无论如何--我会记住的。