V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGPONG
V2EX  ›  程序员

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

  •  
  •   NGPONG ·
    NGPONG · 2020-03-22 19:39:00 +08:00 · 1984 次点击
    这是一个创建于 1705 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设类

    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); }
        }
    
    }
    
    11 条回复    2020-03-22 23:58:04 +08:00
    inhzus
        1
    inhzus  
       2020-03-22 19:49:51 +08:00 via Android   ❤️ 3
    new 确实不方便,但是答应我,都已经 c++20 了,用 vector 不用 new 好吗?

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


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

    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
        7
    codehz  
       2020-03-22 20:16:34 +08:00
    @nightwitch (显然是顺着楼主的思路做啊,你这都改变数据结构了
    codehz
        8
    codehz  
       2020-03-22 20:18:08 +08:00
    @nightwitch (好像我看错了,楼主的结构就是扁平的(
    SamsonWang
        9
    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
        10
    suzper  
       2020-03-22 23:42:09 +08:00 via Android
    @SamsonWang 如果要 new 10000 个 或任意个 Person, 每个都初始化成 name1,你这代码就没法实现这样的扩展了呀!
    ipwx
        11
    ipwx  
       2020-03-22 23:58:04 +08:00   ❤️ 2
    我觉得楼主的需求更接近于:

    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2792 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:02 · PVG 23:02 · LAX 07:02 · JFK 10:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.