cpp 中通过 new 关键字来构建一个对象的数组,不能在构建的过程中就指定需要调用的构造函数吗?

2020-03-22 19:39:00 +08:00
 NGPONG

假设类

public:
    Person(char *personName)
    : m_name(personName) {

    	cout << "Person constructor" << endl;
    }
    Person() {
    
    }

private:
    char *m_name;
};

如下面的创建方式都不好使

int main(void) {

    Person *pers = new (Person((char *)"NGPONG"))[1024];
    Person *pers = new Person((char *)"NGPONG")[1024];
    Person *pers = new Person[1024]((char *)"NGPONG");
}

必须要像 c 一样自己申请一块内存然后自个一个一个 new 吗?

int main(void) {

    Person **pers = (Person **)malloc(sizeof(Person) * 1024);
    if (pers == NULL) { exit(EXIT_FAILURE); }

    for (size_t i = 0; i < 1024; i++) {

        pers[i] = new Person((char *)"NGPONG");
        if (pers[i] == NULL) { exit(EXIT_FAILURE); }
    }

}
1805 次点击
所在节点    程序员
11 条回复
inhzus
2020-03-22 19:49:51 +08:00
new 确实不方便,但是答应我,都已经 c++20 了,用 vector 不用 new 好吗?

vector( size_type count,
const T& value,
const Allocator& alloc = Allocator());
codehz
2020-03-22 20:05:07 +08:00
不仅如此,你释放的时候也得一个一个释放,不然就炸了
你还需要考虑数组中有一个申请失败,怎么按序释放剩下的数组


这就是为啥大家都用 std::vector<std::unique_ptr<T>> (或者里面用 shared_ptr )
codehz
2020-03-22 20:06:29 +08:00
(不过 unique_ptr 也不会自动帮你创建对象,你可以考虑自己写一个类,在构造的时候初始化 unique_ptr
nightwitch
2020-03-22 20:10:14 +08:00
C++20 了,凡是在库外面裸用 new/delete 的都应该反思一下是不是有更好的方式。
就你这个需求而言
栈上可以用 std::array<>构造,堆上用 vector 构造,都能确保任意情况下资源一定不会泄漏。
nightwitch
2020-03-22 20:11:51 +08:00
@codehz vector 里面直接装元素就可以了,vector 的内存在堆上,不需要再套一层 unique_ptr.
gwy15
2020-03-22 20:15:48 +08:00
如果你非做不可,不做全身难受,那可以这样写:

int main(void) {
Person *pers = (Person *)new char[sizeof(Person) * 10];
for (int i = 0; i < 10; i++) {
new (&pers[i]) Person("test");
}
}

但是建议用更现代 c++的方式来做,楼上都说得差不多了。
codehz
2020-03-22 20:16:34 +08:00
@nightwitch (显然是顺着楼主的思路做啊,你这都改变数据结构了
codehz
2020-03-22 20:18:08 +08:00
@nightwitch (好像我看错了,楼主的结构就是扁平的(
SamsonWang
2020-03-22 20:37:45 +08:00
```
#include <iostream>

class Person {
public:
Person(const char* name)
: m_name(name) {
std::cout << "Person constructor" << std::endl;
}
~Person() {
std::cout << "Person destructor" << std::endl;
}

const char* GetName() const {
return m_name;
}

private:
const char *m_name;
};

int main(int argc, char *argv[]) {

Person *pers = new Person[3]{"name1","name2","name3"};

for (int i = 0; i < 3; ++i) {
std::cout << pers[i].GetName() << std::endl;
}

delete[] pers;
pers = nullptr;

return 0;
}
```

gcc 4.8.5 编译命令

```
g++ -std=c++11 test.cpp
```
suzper
2020-03-22 23:42:09 +08:00
@SamsonWang 如果要 new 10000 个 或任意个 Person, 每个都初始化成 name1,你这代码就没法实现这样的扩展了呀!
ipwx
2020-03-22 23:58:04 +08:00
我觉得楼主的需求更接近于:

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/655150

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX