错误、漏洞、问题 - 页 2198

 
fxsaber:

没有区别


在打字时,它似乎取决于你输入的数字。有些人不允许你打字。而他们中的一些人确实如此。

奇怪的行为...如果你输入一个少于12位的整数,它可能会跳过一个超过14位的总数。

我们将拭目以待开发商的说法。

 
请帮助我做一件简单的事情
class A
{
public:  
  int i;
  
  A* operator *( const A &Value ) const
  {
    A* Res = new A;
    
    Res.i = this.i * Value.i;
    
    return(Res);
  }
};

void OnStart()
{
  A a, b, c;
  
  a.i = 2;
  b.i = 3;
  c.i = 5;
  
  A* d = a * b * c;
  
  Print(d.i); // 30
  
  delete d;
}

你可以在代码中清楚地看到,应该有一个内存泄漏。而这正是正在发生的事情。然而,如何正确写出能够 "乘以 "物体?使用 "*="操作符,一切都很清楚,就像在结构中一样。但有了类,如何实现这个简单的功能?


SZZ和这个代码。

class A
{
private:
  A Tmp;
  
public:
  int i;
  
  A* operator *( const A &Value )
  {
    this.Tmp.i = this.i * Value.i;
    
    return(&Tmp);
  }
};

void OnStart()
{
  A a, b, c;
  
  a.i = 2;
  b.i = 3;
  c.i = 5;
  
  A* d = a * b * c;
  
  Print(d.i); // 30
}

用F7使ME崩溃,用F5杀死了终端。为什么我这么幸运!?

 
fxsaber:

ZS 还有这个代码

在F7时使ME崩溃,在F5时杀死终端。为什么我这么幸运?

class A
{
private:
  A Tmp;
  
public:
  int i;
  
  A* operator *( const A &Value )
  {
    this.Tmp.i = this.i * Value.i;
    
    return(&Tmp);
  }
};

void OnStart()
{
  A a, b, c;
  
  a.i = 2;
  b.i = 3;
  c.i = 5;
  
  A* d = a * b * c;
  
  Print(d.i); // 30
}

可能是无限递归和堆栈溢出。

 
Sergey Dzyublik:

可能是无限递归和堆栈溢出。

当然,问题出在被分配的那个地方,但原因似乎更深。

而且在运行时显然不应该有递归。

 
fxsaber:
请帮助我做一件简单的事情
class A
{
public:
  A() {}
  A(const A& other) 
  {
   this.i = other.i;
  }
  
  int i;
  
  A operator *( const A &Value ) const
  {
    A Res;
    
    Res.i = this.i * Value.i;
    
    return(Res);
  }
};

void OnStart()
{
  A a, b, c;
  
  a.i = 2;
  b.i = 3;
  c.i = 5;
  
  A d = a * b * c;
  
  Print(d.i); // 30
}
当然是开销,但如果便利性更重要...
 
Комбинатор:
开销当然会有,但如果便利性更重要...

谢谢你!事实证明,在定义一个对象时,返回对象和"="要经过额外的构造函数。

实际上,我希望在某个地方看到一个清晰的表格,哪些情况被称为构造函数(以及哪些),哪些被称为运算符。现在一切都很直观,这当然是失败的。

 
fxsaber:

实际上,我想在某个地方看到一个表格,在哪里调用构造函数(以及哪些),在哪里调用运算符。现在这一切都停留在直觉的层面上,当然也会失败。

如果你用值返回什么东西,如果是定义,它将通过复制-构造器(如果是相同的类型)分配,如果不是,则通过操作符分配。

void OnStart()
{
  A a, b, c;
  
  a.i = 2;
  b.i = 3;
  c.i = 5;
  
  A d = a * b * c;
  // код аналогичен A d(a * b * c);
  // будет вызван копи-конструктор.

  A e;
  e = a * b * c;
  // будет вызван оператор =
  // но копи-конструктор все равно нужен для множественного умножения
  
  Print(d.i); // 30
}
 
Комбинатор:

如果你用值返回什么东西,如果是定义,它将通过复制-构造器(如果是相同的类型)来分配,如果不是,则通过运算器。

说得很清楚,谢谢你!


SZZ为你的代码打底

class A
{
public:
  A() { Print(__FUNCSIG__); }
  A(const A& other) 
  {
   Print(__FUNCSIG__);
   this.i = other.i;
  }
  
  ~A()
  {
   Print(__FUNCSIG__);
  }
  
  int i;
  
  A operator *( const A &Value ) const
  {
    Print(__FUNCSIG__);

    A Tmp;
    
    Tmp.i = this.i * Value.i;
        
    return(Tmp);
  }
};

void OnStart()
{
  if (true)
  {
    A a, b, c;
    
    a.i = 2;
    b.i = 3;
    c.i = 5;
    
    A d = a * b * c;

    Print(d.i); // 30
  }
  
  Print("Kill!");  
}


结果

void A::A() // a
void A::A() // b
void A::A() // c
A A::operator*(const A&) const
void A::A() // Tmp
void A::A(const A&) // return
void A::~A() // Tmp
A A::operator*(const A&) const
void A::A() // Tmp
void A::A(const A&) // return
void A::~A() // Tmp
void A::A(const A&) // d
30
void A::~A() // a
void A::~A() // b
void A::~A() // c
void A::~A() // d
void A::~A() // return
void A::~A() // return
Kill!

突出显示的几行提出了问题。为什么临时对象没有在使用后立即崩溃?也就是说,在三十岁之前的输出。这样的对象会使我的机器崩溃,因为它应该处理数以千万计的跳动。每个对象都会吞噬数千兆字节的内存,我不希望有这样的临时对象,而不是立即杀死它们。

 
fxsaber:

突出显示的几行提出了问题。为什么临时对象没有在使用后立即崩溃?即在三十岁之前的输出。

通常情况下,临时对象不会被立即删除,而是在上下文结束时删除。

如果你想快速删除,请控制上下文。

void OnStart()
{
  if (true)
  {
    A a, b, c;
    
    a.i = 2;
    b.i = 3;
    c.i = 5;
    
    A d;
    {
      d = a * b * c;
    }

    Print(d.i); // 30
  }
  
  Print("Kill!");  
}

是的,你将不得不使用操作者=

 
A100:

我只有在重启新图的时候才让这个例子工作起来(所有的按钮),这本身就令人费解了。但现在我明白了这一点

随着交易的开启,指定的效果消失了(只在重新启动时)。

对文档进行了编辑。代码的问题是,向图表发送鼠标事件命令只是把命令放到图表的队列中。而如果这个队列没有被处理(例如在周末),图表就不能接收指定的事件。在ChartSetInteger 的描述中加入了一个注释和更正的例子。

注意事项

该函数是异步的--它意味着该函数不等待命令的执行,为指定的图表成功排队,而是立即返回控制。该属性只有在图形队列中处理完命令后才会改变。必须调用ChartRedraw 函数来立即执行图表队列中的命令。

如果你需要立即改变几个图表属性,相应的函数(ChartSetString,ChartSetDouble,ChartSetString)必须在一个代码块中执行,然后ChartRedraw 必须被调用一次。

为了检查执行的结果,你可以使用一个函数来查询指定的图表属性(ChartGetInteger,ChartGetDouble,ChartSetString)。请注意,这些函数是同步的,等待执行的结果。

例子。

//+------------------------------------------------------------------+
//| 专家初始化功能|
//+------------------------------------------------------------------+
空白OnInit()
{
//--- 启用关于鼠标在图表窗口中移动的信息
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1)。
//---- 强制更新图表属性,确保事件处理的准备就绪
ChartRedraw();

}