C++类默认构造函数
早些时候,我问为什么这被认为是不好的:C++类默认构造函数,c++,constructor,class,default,C++,Constructor,Class,Default,早些时候,我问为什么这被认为是不好的: class Example { public: Example(void); ~Example(void); void f() {} } int main(void) { Example ex(); // <<<<<< what is it called to call it like this? return(0); } ??这和简单地调用示例e有什么区别???我知道这是一个函数原型,但似乎有
class Example
{
public:
Example(void);
~Example(void);
void f() {}
}
int main(void)
{
Example ex(); // <<<<<< what is it called to call it like this?
return(0);
}
??这和简单地调用示例e有什么区别???我知道这是一个函数原型,但似乎有些编译器原谅了这一点,允许它调用默认构造函数?我也试过:
class Example
{
private:
Example();
public:
~Example();
};
int main(void)
{
Example e1(); // this works
Example *e1 = new Example(); // this doesn't
return(0);
}
所以我有点困惑:抱歉,如果这个问题被问了一百万次。这将有助于理解这种行为这将有助于理解这种行为这很容易,丹尼尔:
Example *e = new Example();
这看起来不像一个叫做Example的函数,是吗?函数具有返回值、名称和参数。上述情况如何适应
示例e1;//这很有效
是的,因为你不会在任何地方创建任何实例。您只需告诉代码,在周围的命名空间中的某个地方定义了一个函数,您可能希望调用该函数。是的,为了返回一个示例对象,需要创建一个实例。但这并不意味着在这一点上就有了实例。相反,在调用函数时,会在函数中创建一个实例 很简单,丹尼尔:
Example *e = new Example();
这看起来不像一个叫做Example的函数,是吗?函数具有返回值、名称和参数。上述情况如何适应
示例e1;//这很有效
是的,因为你不会在任何地方创建任何实例。您只需告诉代码,在周围的命名空间中的某个地方定义了一个函数,您可能希望调用该函数。是的,为了返回一个示例对象,需要创建一个实例。但这并不意味着在这一点上就有了实例。相反,在调用函数时,会在函数中创建一个实例 嗯。。。好的,这个:
示例e1
不起作用。您可能会认为是这样,或者某些编译器正在接受它,但它并没有创建名为e1的示例实例,它只是声明了一个函数原型。拆下支架,它就可以做你想做的事情
这:
示例*e1=新示例
无法工作,因为构造函数是私有的。如果将构造函数公开,它将在堆上创建对象,e1将是指向该对象的指针。处理完对象后,您需要删除它。嗯。。。好的,这个:
示例e1
不起作用。您可能会认为是这样,或者某些编译器正在接受它,但它并没有创建名为e1的示例实例,它只是声明了一个函数原型。拆下支架,它就可以做你想做的事情
这:
示例*e1=新示例
无法工作,因为构造函数是私有的。如果将构造函数公开,它将在堆上创建对象,e1将是指向该对象的指针。您需要在处理完对象后将其删除。关于新示例是否有效的第一个问题。是的,这是完全合法的C++代码。虽然要完全正确,您需要在从main返回之前删除对象,否则将导致内存泄漏 例如:
int main(void)
{
Example *e = new Example();
delete e;
return(0);
}
最后一个问题。线路示例e1;有效,因为它正在声明函数原型。这实际上不会导致机器代码执行良好,可能是堆栈空间。简单地说,有一个没有参数的函数原型,返回一种示例类型
然而,第二行肯定会失败。例如,此时您正试图实际执行构造函数。这是不合法的,因为函数的可访问性是私有的,因此编译器错误。对于第一个问题,新示例是否有效。是的,这是完全合法的C++代码。虽然要完全正确,您需要在从main返回之前删除对象,否则将导致内存泄漏 例如:
int main(void)
{
Example *e = new Example();
delete e;
return(0);
}
最后一个问题。线路示例e1;有效,因为它正在声明函数原型。这实际上不会导致机器代码执行良好,可能是堆栈空间。简单地说,有一个没有参数的函数原型,返回一种示例类型
然而,第二行肯定会失败。例如,此时您正试图实际执行构造函数。这是不合法的,因为函数的可访问性是私有的,因此编译器错误。 我认为您应该区分“解析”、“编译”、“链接”和“WorkWork”,并尝试像C++解析器/编译器/链接器一样思考,以查看第一个例子。
Example e1(); // function prototype
看起来像一个函数声明。解析器将理解它,因此您不能调用e1上的成员函数。编译器将生成一个符号,引用它尚未看到的某个函数,但由于该函数未被使用,因此它不会抱怨。如果添加此代码,它将:
e1.f();// since e1 is a function, it has no member 'f' => compiler error
作为旁注:此代码还将编译:
int a_function_prototype(int); // another prototype.
e1(); // should work!
a_function_prototype(5);
但是在编译器运行完之后
链接器将开始查找实际的函数体,但找不到任何函数体
现在自从排队
Example* e = new Example();
包含编译器识别的关键字new,并且它知道只能在新对象的分配+构造中找到它,它将生成代码来执行此操作。我认为您应该区分“this parses”、“this compiles”、“this links”和“this works”,并尝试像C++解析器/编译器/链接器一样自己思考,以查看第一个例子
Example e1(); // function prototype
看起来像一个函数声明。解析器将理解它,因此您不能调用e1上的成员函数。编译器将生成一个符号,引用它尚未看到的某个函数,但由于该函数未被使用,因此它不会抱怨。如果添加此代码,它将:
e1.f();// since e1 is a function, it has no member 'f' => compiler error
作为旁注:此代码还将编译:
int a_function_prototype(int); // another prototype.
e1(); // should work!
a_function_prototype(5);
但是在编译器完成后,链接器将开始查找实际的函数体,并且找不到任何函数体
现在自从排队
Example* e = new Example();
包含编译器识别的关键字new,并且它知道只能在新对象的分配+构造中找到它,它将生成执行此操作的代码。这与在堆栈中分配内存有关,而不是与默认构造函数有关。这与在堆栈中分配内存有关,而不是与默认构造函数有关示例e1;也没有returnvalue,但它看起来仍然像一个函数。我宁愿说=-符号和new关键字清楚地表明这是一个分配+构造函数调用,其结果存储在新声明的指针变量Xtoly中。示例e1;有一个返回类型,这是其中的例子:它几乎5年后。。。我在寻找一个稍微不同的话题,但这是一个很好的答案,对这个问题的简单回答;然而,我一直把它看作是一种讽刺,我花了一段时间才明白。对于其他可能像我一样慢的人:第一行是创建指向示例对象的指针并调用默认构造函数,而第二行是日常函数原型;也没有returnvalue,但它看起来仍然像一个函数。我宁愿说=-符号和new关键字清楚地表明这是一个分配+构造函数调用,其结果存储在新声明的指针变量Xtoly中。示例e1;有一个返回类型,这是其中的例子:它几乎5年后。。。我在寻找一个稍微不同的话题,但这是一个很好的答案,对这个问题的简单回答;然而,我一直把它看作是一种讽刺,我花了一段时间才明白。对于其他可能像我一样慢的人:第一行是创建一个指向示例对象的指针并调用默认构造函数,而第二行是一个日常函数原型。嘿,谢谢。所以我想这是一个令人烦恼的解析问题。是的,太棒了,我总是用e作为例子;从来没有遇到过微软VC++VS 2005和gnu g++的问题不记得版本了。所以这对我来说是全新的。。。。我猜你每天都会学到新东西。嘿,谢谢。所以我想这是一个令人烦恼的解析问题。是的,太棒了,我总是用e作为例子;从来没有遇到过微软VC++VS 2005和gnu g++的问题不记得版本了。所以这对我来说是全新的。。。。我猜你每天都会学到新东西。