【问题标题】:C++ one argument boolean constructor and "new" keyword: Logic ErrorC++ 一个参数布尔构造函数和“new”关键字:逻辑错误
【发布时间】:2012-11-15 14:26:30
【问题描述】:

我在 c++ 中有以下类

class MyClass {

public:
  bool flag;

  MyClass (bool flag = false) {
    this->flag = flag;
  }
...
};

在我的主要(用于测试)中,我有类似的东西

int main() {
 MyClass number1 = MyClass(true);
 MyClass number2 = MyClass(false);
 MyClass number3 = new MyClass(false);
 MyClass number4 = new MyClass(true);
 MyClass number5 = new MyClass();
 std::cout << number1.flag << number2.flag << std::endl;
 std::cout << number3.flag << number4. flag << number5.flag << std::endl;
}

我的输出(想象布尔输出真或假,输出格式更好)

true, false 
true, true, true

问题是当我使用“new”关键字创建一个“MyClass”对象时,无论我在参数构造函数中做什么或不做什么,它都会始终将标志变量设置为 true。

它适用于不使用“new”的构造函数,但不适用于使用它的构造函数。我知道使用和不使用关键字 new 之间的唯一真正区别是,如果不使用它,则在堆栈上创建变量,否则在堆上创建变量。我看不出这会一直出错。

如果我想让它正常工作,需要改变什么? 我在类中确实有其他方法可以成功修改标志变量,但初始化它不起作用。我也尝试使用成员初始化列表来构造变量,但这也不起作用。

感谢您的帮助!

编辑:这是编译的代码。我有两个文件,Test.c++ 和 AbstractCell.h。 AbstractCell 是 MyClass,当此代码运行时,它会输出“isAlive: 1”

 void test_abstract_2(){
   AbstractCell one = new AbstractCell();

      std::cout << std::endl <<  "isAlive:  " << one.alive << std::endl;

  }

【问题讨论】:

  • 该代码不应该编译。 new 返回一个指针。
  • 您从未运行过该代码,它根本无法编译!
  • 对我来说编译得很好,是 include 和 return 0; 的缩写。没有理由不以当前形式编译。
  • 。 . .它确实可以编译。 . .所以呀。 . .我跑了。 . .这就是我知道输出错误的方式。 . .啊啊啊啊啊
  • Aside:尽可能在构造函数中使用初始化列表,例如:MyClass (bool flag = false) : flag(flag) { }

标签: c++ constructor arguments


【解决方案1】:

new 返回的指针被隐式转换为bool,然后传递给MyClass(bool)

换句话说,如下:

MyClass number3 = new MyClass(false);

相当于:

MyClass number3(bool(new MyClass(false)));

由于new 返回的指针永远不会为空,因此转换总是产生true,这是传递给number3 的构造函数的内容。新分配的指针被泄露。

你可能是想说:

 MyClass* number3 = new MyClass(false);
 MyClass* number4 = new MyClass(true);
 MyClass* number5 = new MyClass();

(注意星号。)

如果你声明构造函数explicit,你就不会遇到这个问题:

  explicit MyClass (bool flag = false) {
    this->flag = flag;
  }

代码将无法编译,它会立即告诉您有问题。

【讨论】:

  • 我可能是错的,但这不会涉及 3 次隐式转换(不允许 IIRC)吗?
  • 啊哈!我是一个白痴。这行得通。它确实编译。我确实使用以下来编译它。 . . (也使用 valgrind) g++ -pedantic -std=c++0x -lcppunit -ldl -Wall TestLife.c++ -o TestLife.c++.app
  • @Pubby 这只是一种隐式转换,从指针到布尔值。
  • @user1348913:添加以下标志:-Wall -Wextra -Werror -ansi
【解决方案2】:

你有两个问题:

第一个是new返回一个指针,而不是一个静态对象。你通常这样使用它:

MyClass* number3 = new MyClass(false);
std::cout<<std::boolalpha<<number3->flag<<std::endl;  //outputs 'false'
...  //do more stuff with number3
delete number3;

第二个问题是代码按照编写的方式编译。 编辑:我认为代码通常不应该按照编写的方式编译,但我认为我错了。在 C++ 中,似乎有太多东西可以隐式转换为 bool。

所以我会修改它并说第二个问题是代码通过构造不会被破坏的匿名临时动态对象来泄漏内存:)

【讨论】:

  • 谢谢。我测试了类似的东西,但当然我没有使用 bool 的构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多