C++ 为什么使用构造函数而不是函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9752437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why constructor is used instead of functions?
提问by Rafay Zia Mir
This is a very basic question, I searched it but i just want to ask this community that we have both constructors
and methods
. But normally we use constructor to initialize the variables instead of the methods. I think that both can be used to initialize variables. So what is the basic difference between both. Is there any solid reason?
this is a very basic question so bear it for sake of beginner level.
thanks in advance..
这是一个非常基本的问题,我搜索了它,但我只想问这个社区我们有constructors
和methods
。但通常我们使用构造函数来初始化变量而不是方法。我认为两者都可以用来初始化变量。那么两者之间的基本区别是什么。有什么可靠的理由吗?这是一个非常基本的问题,所以为了初学者水平,请忍受。提前致谢..
采纳答案by Doug T.
The most important difference: When you instantiate an object it's constructor will be invoked whereas calling a method is always optional. You therefore might forget to call your initialization method and fail to initialize everything correctly.
最重要的区别:当您实例化一个对象时,它的构造函数将被调用,而调用方法始终是可选的。因此,您可能会忘记调用初始化方法并且无法正确初始化所有内容。
For example, all these normal ways of instantiating an object will call the constructor
例如,所有这些实例化对象的正常方法都会调用构造函数
Foo* p = new Foo();
Foo p;
Or if you have mandatory arguments, don't define a default constructor and instead require construction with parameters:
或者,如果您有强制参数,请不要定义默认构造函数,而是需要带参数的构造:
class Foo
{
private:
Foo();
public:
Foo(int param1, double param2)
};
This has the advantage of requiring the arguments before you even instantiate the class. So you're forced to do:
这具有在您甚至实例化类之前要求参数的优点。所以你不得不这样做:
Foo* p = new Foo(1, 5.0);
and failing to construct with valid arguments becomes a compiler error:
并且无法使用有效参数进行构造会导致编译器错误:
Foo* p = new Foo(); // compiler error
So whenever possible, always err on the side of doing your initialization in a constructor. There are a few cases where a constructor might not be viable. For example, the only way to fail a constructor is by using an exception. The failure to construct may be "routine" and not truly exceptional. Also exceptions might be expensive on some architectures. Another case might be when you want to ensure that virtual methods are fully bound, which is guaranteed to be true only after construction.
因此,只要有可能,总是在构造函数中进行初始化时出错。在某些情况下,构造函数可能不可行。例如,使构造函数失败的唯一方法是使用异常。构建失败可能是“例行公事”,而不是真正的例外。在某些体系结构上,异常也可能很昂贵。另一种情况可能是当您想要确保虚拟方法是完全绑定的,这保证只有在构造之后才为真。
回答by Oliver Charlesworth
They can't both be used to initialize member variables. It is the job of the constructor to initialize members, and it is called automatically whenever you create a new instance.
它们不能同时用于初始化成员变量。初始化成员是构造函数的工作,每当您创建新实例时都会自动调用它。
Consider the following:
考虑以下:
class Foo {
public:
// Constructor
Foo() : x(53) // Initialise x
{}
void bar() {
x = 42; // Error, attempt to *assign* a const member!
}
private:
const int x;
};
Without the constructor, there would be no way to initialise member x
.
如果没有构造函数,就无法初始化 member x
。
回答by chrisaycock
Constructors are called automatically, so there's no need to worry whether the user has invoked an initialization method yet. However, the Google style guide does have something to say about constructors:
构造函数是自动调用的,因此无需担心用户是否调用了初始化方法。然而,谷歌风格指南确实有关于构造函数的内容:
- There is no easy way for constructors to signal errors, short of using exceptions.
- If the work fails, we now have an object whose initialization code failed, so it may be an indeterminate state.
- If the work calls virtual functions, these calls will not get dispatched to the subclass implementations. Future modification to your class can quietly introduce this problem even if your class is not currently subclassed, causing much confusion.
- If someone creates a global variable of this type, the constructor code will be called before main(), possibly breaking some implicit assumptions in the constructor code.
- 除了使用异常之外,构造函数没有简单的方法来发出错误信号。
- 如果工作失败,我们现在有一个初始化代码失败的对象,所以它可能是一个不确定的状态。
- 如果工作调用虚函数,这些调用将不会被分派到子类实现。即使您的类当前没有被子类化,未来对您的类的修改也会悄悄地引入这个问题,从而造成很多混乱。
- 如果有人创建了这种类型的全局变量,构造函数代码将在 main() 之前调用,这可能会破坏构造函数代码中的一些隐含假设。
Google's recommendation is to have straightforward initiation in a constructor, and non-trivial initiation in a separate method.
Google 的建议是在构造函数中直接启动,并在单独的方法中进行非平凡启动。
回答by vaisakh
Initializing variables is no doubt, a very important programming practice. when using classes, the option is to initialize them inside methods. Thus, we have two steps:-
初始化变量无疑是一个非常重要的编程实践。使用类时,选项是在方法中初始化它们。因此,我们有两个步骤:-
- Define the method
- Call the method to perform the initialization
- 定义方法
- 调用方法执行初始化
But if the 'calling of method' is forgotten, variables end up having junk values. To make life easier for the programmer, concept of a constructor method was brought in.
但是如果忘记了“方法调用”,变量最终会产生垃圾值。为了让程序员的生活更轻松,引入了构造函数方法的概念。
With Constructors, we just have one step:-
使用构造函数,我们只需一步:-
- Define the constructor
- 定义构造函数
The 'calling part' is performed automatically whenever a new Object of the class is created.
每当创建类的新对象时,“调用部分”就会自动执行。
回答by c geek
Constructors can be used for efficient memory management, which is not possible with functions.
构造函数可用于高效的内存管理,这是函数无法实现的。
Destructor can be used to destroy the constructors when not needed.
析构函数可用于在不需要时销毁构造函数。
Moreover, the use of copy constructor is known to prevent difficulties or errors due to memory mis happenings.
此外,已知使用复制构造函数可以防止由于内存错误发生而导致的困难或错误。
回答by Gangadhar
The constructor is invoked automatically when you create the object unlike a function. Also, the constructor is used to indicatethe intent that this is for the initialization of the object.
与函数不同的是,当您创建对象时,会自动调用构造函数。此外,构造函数用于指示这是用于对象初始化的意图。
回答by Ivaylo Strandjev
Imagine you have a member variable that has no empty constructor. Then you have no other option but to initialize it in the initializer list of your constructor.
假设您有一个没有空构造函数的成员变量。然后你别无选择,只能在构造函数的初始化列表中初始化它。
Also the constructor is called when you allocate an array with the new operator, while initialization with methods will make the code way more complicated.
当您使用 new 运算符分配数组时,也会调用构造函数,而使用方法进行初始化会使代码方式更加复杂。
In general having complex logic in the constructor is not very good idea, but simple initialization should be done there(the things you need to do to ensure that your object is in some valid state).
一般来说,在构造函数中有复杂的逻辑并不是一个好主意,但应该在那里完成简单的初始化(您需要做的事情以确保您的对象处于某种有效状态)。