MQL5中的OOP问题 - 页 45

 
Dmitry Fedoseev:

谁能解释一下,这种初始化字段的方式比这个好吗?

是比这更好的。

那到底有什么意义呢?

const字段可以被初始化。

 
Dmitry Fedoseev:

谁能解释一下,这种初始化字段的方式比这个好吗?

是比这更好的。

那到底有什么意义呢?

在第一种情况下,你有初始化,而在第二种情况下--对默认的初始化字段进行操作。所以这完全取决于编译器,要么没有区别,要么在运行时有大量的额外动作。在正数中,第二个变体被认为是不好的形式。
 
=运算符,正如它应该的那样,返回r值(5<(val=7)有效),但就在携带语义方面,这里没有,而且它被问到了,很遗憾,所以也没有携带构造函数。
 
Igor Makanu:

这个问题纯粹是理论性的。

可能在SB中看到过这样的构造器调用。

这个代码会有什么不同。

我已经解压了,我没有看到任何区别,那么请具体一点--什么或者为什么我们可以对a1和a2对象使用强制构造函数调用?

第一个选项的 "便利 "是什么?

第一个选项被称为--价值初始化,第二个选项是--默认初始化。有一些微妙的差别取决于对象的类型(它是一个集合体还是有默认构造函数,...)。例如,这里的结果在使用括号和不使用括号时将绝对不同。

#include <iostream>
using namespace std;
struct S {
        int i;
        int q;
        int f;
};
struct Q : S {
        Q():S() {}
        //Q() {}
};
int main() {
        Q s;
        cout << s.i << s.q << s.f << endl;
}

如果你想掌握理论,直到你的耳朵,去这里https://en.cppreference.com/w/cpp/language/initialization

ZS:这与MCL并不完全相关,但作为对参考模型的理解。

Initialization - cppreference.com
  • en.cppreference.com
Initialization of a variable provides its initial value at the time of construction. The initial value may be provided in the initializer section of a declarator or a new expression. It also takes place during function calls: function parameters and the function return values are also initialized. For each declarator, the initializer may be one...
 
Vict:

如果你想在理论上有所建树,请到这里来https://en.cppreference.com/w/cpp/language/initialization

还没有必要,但我会保存它,这样我就知道在哪里可以读到来源。

谢谢大家!

弗拉基米尔-西马科夫
在正数中,第二个选项被认为是不好的形式。

当有必要在类中编写多个构造函数时,将会出现我遇到的同样问题--字段初始化的代码重复。

如果你使用变体2,你可以把重复的代码放在一个单独的方法中,并在每个构造函数中执行必要的操作后调用这个方法(我通过结构进行类的初始化,变体2通过写这个结构的数据的文件名(备份保存))。


写出这种重复的代码是不好的...这并不有趣,但问题是,如果我在类中添加一个新的字段,我必须记住像构造函数一样多次初始化这个字段--事实上,这并不方便,但事实上,你可以忘记做N次,这是一个问题,我认为

 
Igor Makanu:

还没有必要,但我会保留它,这样我就知道在哪里可以读到原始资料。

谢谢大家!

当有必要在类中编写多个构造函数时,将会出现我遇到的同样问题--字段初始化的代码重复。

如果你使用变体2,你可以把重复的代码放在一个单独的方法中,并在每个构造函数的必要操作后调用这个方法(我通过结构进行类的初始化,变体2通过写有该结构数据的文件名(备份保存))。


写出这种重复的代码是不好的...这 并不有趣,但问题是,如果我在类中添加一个新的字段,我必须记住像构造函数一样多次初始化这个字段--事实上,这并不方便,但事实上,你可以忘记做N次,这是一个问题,我认为

一个宏,也可以是参数化的。遗忘(我自己也有这个毛病),也用这个))))。

 
Igor Makanu:

会出现我遇到的同样的问题--当需要在类中编写多个构造函数时,会出现字段初始化代码的重复。

如果你使用变体2,你可以把重复的代码放在一个单独的方法中,并在每个构造函数中的所有必要动作后调用这个方法(我通过结构进行类的初始化,变体2通过写这个结构的数据的文件名(备份保存))。


写出这种重复的代码是不好的...这并不有趣,但问题是,如果我在类中添加一个新的字段,我将不得不记住初始化这个字段,因为有很多构造函数--事实上,这并不方便,但事实上,你可能忘记做N次,这是一个问题,我认为

来吧,一切都可以解决。

class Q {
    void ctr_base(T t, S s) {//make init tasks
        }
public:
    Q(T t, S s, int i) {
        // make base init
        ctr_base(t, s);
        // make additional tasks
        ...
    }
    Q(T t, S s, strint str) {
        // make base init
        ctr_base(t, s);
        // make additional tasks
        ...
    }
};

我不反对默认构造函数(或默认初始化),但如果你的构造函数让对象(好吧,如果它不是一个愚蠢的聚合体)处于未定义状态,然后你通过一些拐杖对其进行初始化,那么你就做错了。

ZS:顺便说一下,你可以在专业人员中委托构造函数,当然缺少

class Foo {
public: 
  Foo(char x, int y) {}
  Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
};
 
Vict:

来吧,这是可以解决的。

比我早一点,刚在电脑前坐下。

@Vladimir Simakov的 建议是用宏来初始化类的字段,不要忘记正确的初始化,嗯,是的--好的技巧,但是代码会读起来像调用一个初始化字段的方法,很难假设这是一个好的基调...


你的例子也不是最精炼的,但它解决的问题正是我现在做的方式--一个单独的初始化方法。

我认为,这是一个目的问题--正确的方法是写一个带有所有必要字段的基类,从它那里继承,使构造函数受保护,并从继承人那里初始化基类,从而将保护 "遗忘"--没有默认的构造函数,对吗?- 所以至少你可以在谷歌上搜索 "受保护的构造函数",可以看到米克尔公司的文章。


我的问题有点不同,我特意离开了继承,把类的字段的状态保存到一个文件中,我有2个类的字段,它们的状态也通过调用相应的方法保存在同一个文件中。当我从一个基类中继承时,我试图把它全部保存下来,它变得非常混乱,我重写了它,没有继承,现在一切都变得 "透明 "了。

 
Igor Makanu:

比我早一点,刚在电脑前坐下。

@Vladimir Simakov的 建议是使用宏来初始化类的字段,以避免忘记正确的初始化,嗯,是的--好的技巧,但是代码会读起来像对初始化字段的方法的调用,很难假设这个语气有多好...


你的例子也不是最精炼的,但它解决的问题正是我现在做的方式--一个单独的初始化方法。

我认为,这是一个目的问题--正确的方法是写一个带有所有必要字段的基类,从它那里继承,使构造函数受保护,并从继承人那里初始化基类,从而将保护 "遗忘"--没有默认的构造函数,对吗?- 所以至少你可以在谷歌上搜索 "受保护的构造函数",可以看到米克尔公司的文章。


我的问题有点不同,我特意离开了继承,把类的字段的状态保存到一个文件中,我有2个类的字段,它们的状态也通过调用相应的方法保存在同一个文件中。 当我从基类中继承时,我试图保存所有的东西,它变得非常复杂; 我在没有继承的情况下重写了,现在一切都变得 "透明 "了。

这有什么好困惑的?

...
virtual void CBase::Save(int hndl){...}
...
CObj:public CBase
...
void CObj::Save(int hndl){
   CBase::Save(hndl);
   ...
}
 
Vladimir Simakov:

这有什么好困惑的?

这正是我所逃避的,起初我也是这样做的。

用这种方法--从一个基类继承,"一切都在那里"--一切都可以,但直到我们想尝试做几个类的字段,然后我们想在每个字段类中添加几个字段,用一个动态的数组 来钉住这一切

然后我们会得到,我们不能在基类中实现Save(int hndl)方法本身--这个方法实际上是一个接口,正如上面所讨论的,根本不需要--你可以不用接口来写它

我通常在代码的灵活性方面做出最大的努力--最小的麻烦--结果是解决了一个新的问题,愿我的术语得到原谅)))。


问题是,在实现保存到文件时,你需要制定文件头,它应该描述不同类型的条目总量,然后你需要不失去数据保存的逻辑/顺序,以便正确读取所有内容....。最后的结局是,如果你改变了一个类中的哪怕一个字段

我认为,这种从基类中 "轻松 "继承的做法是很费力的,因为要开发和维护一个小的数据库,不断监测任何类的变化。