c++对象实例化和作用域
C++ object instantiation and scope
我是从c#来的(最近),我习惯于像这样实例化对象:
Phone myPhone = new Phone();
直接写
Phone myPhone;
实际上是为类创建了一个holder,但是还没有初始化。
现在我正在用c++写一个小类,我有一个问题。下面是伪代码:
Phone myPhone;
void Initialise()
{
myPhone = new Phone();
}
void DoStuff()
{
myPhone.RingaDingDong();
{
实际上这有点误导,因为上面的代码是我想要的,因为我想把我所有的初始化代码放在一个整洁的地方。我的问题是,在c++中,initialize里面的行是不必要的,因为在那之前,一个新的实例已经被第一行创建和初始化了。另一方面,如果我把第一行在initialize()我不能再访问它在DoStuff。它超出了范围,(更不用说在c++中使用"new"和不使用"new"之间的区别了)。如何为类变量创建一个简单的持有人,以便我可以在一个地方初始化它,并在另一个地方访问它?还是说我从根本上就错了?
提前感谢!
如果你的Phone构造函数没有参数,那么你的生活就很简单了——你不需要在Initialize方法中新建这个Phone。它将在创建对象时为您创建,并且将为您管理生命周期。
如果你需要为它获取参数,而它没有Initialize()方法或一些set方法,那么你可能需要使用一个指针(有时可能为空),并让Initialize()调用new并传递这些参数。其他代码需要在使用指针之前检查它是否为空。此外,您还需要管理生命周期(通过编写大3)或使用智能指针,如c++ 11中的shared_ptr。
可以在指针上使用new操作符:
Phone *myPhone;
void Initialise()
{
myPhone = new Phone();
}
void DoStuff()
{
myPhone->RingaDingDong();
}
仅在myPhone
声明中增加了*
,在访问RinaDingDong()
时增加了->
而不是.
。您还必须释放它,因为new
正在分配内存:
void destroy()
{
delete myPhone;
}
注意,如果你这样做,myPhone
将是一个指向Phone
的指针,而不是一个实际的Phone
。
我认为你需要在指针上刷一下。你所要做的是可以用指针来实现的。
我的问题是,在c++中,initialize里面的行是不必要的,因为在那之前,一个新的实例已经被第一行创建和初始化了。
这是不正确的。您提供的注释仅对构造函数有效。从您的puesdo代码中,函数initialize
是一个全局函数,而不是类的成员函数。
另一方面,如果我把第一行放在initialize()中,我就不能再在DoStuff中访问它了。它超出了范围,(更不用说在c++中使用"new"和不使用"new"之间的区别了)。
请参考有关指针的书籍,您可以使用全局指针并使用new
进行初始化。这可以在doStuff
如果你学过c#,你就知道有两种类型的对象:类和结构。
类被复制、赋值并通过引用传递给函数。所以,他们使用的是参考语义。类也在堆中分配(使用new)。
结构体实现了值复制语义。Struct类型在栈上分配(int、double和其他内置类型都是Struct)。不能以多态方式处理结构体。
在c++中没有这个区别。类和结构本质上是相同的(一部分是默认访问级别)。决定复制语义的不是类的声明,而是类的实例声明。
如果你创建一个指针,其行为与c#中的类非常相似。如果你创建一个对象,其语义将类似于c#中的结构体。
c++也有引用,你应该阅读一下指针和引用的区别
Kate Gregory的回答是正确的,但是我想详细说明一下。c++中一个更强大的思想是,堆栈分配的对象由其包含作用域拥有。例如,如果你想写一个包含电话的类,你只需这样写:
class Secretary {
Phone myPhone;
};
现在每次创建秘书时,都会用默认构造函数自动初始化Phone对象。更重要的是,每当Secretary对象被销毁时,其包含的Phone对象也会被销毁。如果你想为Phone使用不同的构造函数,你可以在Secretary的构造函数中使用初始化列表:
class Secretary {
private: // members
Phone myPhone;
Phone myCellPhone;
public: // methods
Secretary() : myPhone("phone constructor", 12, " args") {}
};
在这个例子中,myPhone是用它的3参数构造函数初始化的,myPhone是用它的默认构造函数初始化的。
- 在类函数中初始化外部作用域变量
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- 即使我正在.cpp文件中实例化一个伪对象,.cpp文件内模板函数的定义也不起作用
- 为什么显式模板实例化不起作用
- 无法从派生类型的作用域访问另一个实例的受保护成员
- 为什么显式模板实例化不起作用?
- 函数作用域是静态变量还是线程本地变量在C++11中的第一个条目中初始化
- 使用作用域内生成的指针初始化静态成员
- 主线程中块作用域static与命名空间作用域thread_local的初始化和销毁顺序
- 在自动作用域中使用实例时需要"public"访问修饰符
- 在c++中,全局作用域中只允许"表达式"初始化全局对象.我在哪里可以在标准中找到这个
- 未在此作用域中声明实例化类/的作用域
- 有没有一个C++版本在循环结束后将在for循环初始化中声明的变量保留在作用域中
- C++ 类模板显式实例化在 macOS 上工作,在 ubuntu 上不起作用
- 在 Arduino 环境中实例化类时串行通信不起作用
- 使用具有相同名称的(无作用域)基类枚举初始化派生类枚举
- 函数作用域的静态非 Pod 对象初始化
- 在使用包含类的动态实例化后调用 c++ 重载运算符 [] 似乎不起作用
- 隐式实例化取决于作用域或非作用域枚举
- c++对象实例化和作用域