C++ 如何为全局对象、对象数组和类/结构中的对象调用构造函数?
在这三种情况下,您将如何调用以下类的构造函数:全局对象、对象数组和包含在另一个类/结构中的对象 具有构造函数的类(在所有三个示例中使用): 下面是我调用此构造函数的尝试:C++ 如何为全局对象、对象数组和类/结构中的对象调用构造函数?,c++,oop,constructor,C++,Oop,Constructor,在这三种情况下,您将如何调用以下类的构造函数:全局对象、对象数组和包含在另一个类/结构中的对象 具有构造函数的类(在所有三个示例中使用): 下面是我调用此构造函数的尝试: class Bar { Foo foo; Bar() : foo(3) { } }; 全局对象 对象数组 在这里,我试图为数组的所有元素调用构造函数,但我也想知道如何对单个元素调用它 类/结构中包含的对象 全局对象 你的是唯一的办法。另一方面,尽量避免这种情况。最好使用函数(甚至其他对象)作为工厂。这样,您
class Bar {
Foo foo;
Bar() : foo(3) { }
};
全局对象
对象数组
在这里,我试图为数组的所有元素调用构造函数,但我也想知道如何对单个元素调用它
类/结构中包含的对象
全局对象
你的是唯一的办法。另一方面,尽量避免这种情况。最好使用函数(甚至其他对象)作为工厂。这样,您就可以控制创建时间
Foo& getGlobalA() // passed parameters can be passed to constructor
{
static Foo A;
return A;
}
Foo& getGlobalB()
{
static Foo B;
return B;
}
etc.
对象数组
没有办法直接做到这一点。非POD对象将始终默认构造<代码>标准::填充通常是一个很大的帮助。您可能还想查看分配器和std::uninitialized\u fill
类/结构中包含的对象
在构造函数中使用初始化列表:
class Bar {
Foo foo;
Bar() : foo(3) { }
};
静态成员实际上必须在类之外定义:
class Bar {
static Foo foo;
};
Foo Bar::foo(3);
对于全局情况,无法控制何时调用它。C++规范实际上表示它将在主()之前调用,并且在某个时候被销毁。除此之外,“编译器可以随心所欲 在第一个数组中,您创建的是一个Foo对象的静态数组。默认情况下,数组中的每个值都将使用默认构造函数Foo()初始化。没有一个原始的C++数组来强制调用特定的重载构造函数。您可以通过切换到向量而不是数组来推断一点控制。向量构造函数有一个重载的构造函数向量(size,defaultValue),它应该可以实现您想要的。但在这种情况下,您必须小心,因为它不会调用Foo(3),而是调用Foo(constfoo&other),其中other是Foo(3) 第二种情况与第一种情况非常相似。唯一真正的区别是内存的分配位置(在堆上而不是堆栈上)。它在调用构造函数方面有相同的限制 所包含的案例是另一个问题。C++在对象内字段的定义和字段的初始化之间有明显的分离。要使它在C++中工作,需要将bar定义更改为以下
class Bar{
Foo foo;
Bar() : foo(3){}
};
要纠正对globals的一些误解,请执行以下操作:
- 顺序在编译单元中定义良好。
- 这与定义的顺序相同
- 编译单元之间的顺序未定义
- 毁灭的顺序与创造的顺序正好相反
基本上,您可以让函数返回对所需全局的引用(在函数中定义全局)。它将在首次使用时创建(并按与创建相反的顺序销毁)
康拉德的回答是可以的,只是对阵列的一种虚拟化。。。。 有一种方法可以创建项目数组(不是指针),如下所示:
//allocate raw memory for our array
void *rawMemory = operator new[](30 * sizeof(Foo))
// point array_of_foos to this memory so we can use it as an array of Foo
Foo *array_of_foos = static_cast<Foo *>(rawMemory);
// and now we can create the array of objects(NOT pointers to the objects)
// using the buffered new operator
for (int i = 0; i < 30; i++)
new(array_of_foos[i])Foo(3);
//为阵列分配原始内存
void*rawMemory=运算符new[](30*sizeof(Foo))
//指向这个内存的数组,这样我们就可以将它用作一个Foo数组
Foo*array\u of\u foos=static\u cast(rawMemory);
//现在我们可以创建对象数组(而不是指向对象的指针)
//使用缓冲的new运算符
对于(int i=0;i<30;i++)
新的(数组)foos[i])Foo(3);
这里描述了这种方法:构建对象数组: 可以使用默认参数修改原始示例 目前只支持默认构造函数。
这是下一个版本正在解决的问题(因为每个人都会问这个问题)C++0X初始值设定项列表解决了对象数组的问题。请看赫伯·萨特的博客,他在博客中详细描述了他们 同时,您可能可以像这样解决问题:
class Foo {
public:
Foo(int a) : b(a) {}
private:
int b;
};
class Foo_3 : public Foo {
public:
Foo_3() : Foo(3) {}
};
Foo_3 array_of_foos[30];
这里,Foo_3
类的存在仅仅是为了用正确的参数调用Foo
构造函数。您甚至可以将其作为模板:
template <int i>
class Foo_n : public Foo {
public:
Foo_n() : Foo(i) {}
};
Foo_n<3> array_of_foos[30];
模板
食品类:公共食品{
公众:
Foo_n():Foo(i){}
};
Foo_n数组_of_foos[30];
同样,这可能并不完全符合您的要求,但可能会提供一些思考的素材
(还要注意,在
Foo
类中,您确实应该养成在构造函数中使用成员初始值设定项列表而不是赋值的习惯,正如我上面的示例所示)在这个线程中,似乎有一个一般要点,除了使用默认构造函数之外,您不能初始化数组的成员。一个答案甚至创建了另一个类型,只是为了调用另一个构造函数。即使您可以(如果数组不是类成员的一部分!):
但是,类型需要是可复制的:给定的项被复制初始化到数组的成员中
对于类中作为成员的数组,目前最好使用容器:
struct bar {
/* create a vector of 100 foo's, initialized with "initial" */
bar(): f(100, foo("initial")) { }
private:
std::vector<foo> f;
};
结构栏{
/*创建一个100个foo的向量,用“initial”初始化*/
bar():f(100,foo(“首字母”){}
私人:
std::向量f;
};
使用andy.gurin描述的新的技术也是一种选择。但请注意,这会使事情复杂化。你必须自己调用析构函数。如果有构造器抛出,而您仍在构建数组,那么您需要确定停止的位置。。。总之,如果您想在类中拥有数组,并想对它们进行初始化,请使用std::v
class Foo {
public:
Foo(int a) : b(a) {}
private:
int b;
};
class Foo_3 : public Foo {
public:
Foo_3() : Foo(3) {}
};
Foo_3 array_of_foos[30];
template <int i>
class Foo_n : public Foo {
public:
Foo_n() : Foo(i) {}
};
Foo_n<3> array_of_foos[30];
struct foo {
foo(int a): a(a) { }
explicit foo(std::string s): s(s) { }
private:
int a;
std::string s;
};
/* global */
foo f[] = { foo("global"), foo("array") };
int main() {
/* local */
foo f[] = { 10, 20, 30, foo("a"), foo("b") };
}
struct bar {
/* create a vector of 100 foo's, initialized with "initial" */
bar(): f(100, foo("initial")) { }
private:
std::vector<foo> f;
};