You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确初始化结构体及用结构体初始化std::unique_ptr?

问题描述

以下代码编译报错:

int main()
{
    struct test
    {
        std::string s;
    };

    std::unique_ptr<struct test> p = nullptr;

    p = std::make_unique<struct test>("test");

    printf("%s\n", p->s);
}

编译错误信息:

In file included from /usr/include/c++/14/memory:78,
                 from struct-pointer.cc:2:
/usr/include/c++/14/bits/unique_ptr.h: In instantiation of ‘std::__detail::__unique_ptr_t<_Tp> std::make_unique(_Args&& ...) [with _Tp = main()::test; _Args = {const char (&)[5]}; __detail::__unique_ptr_t<_Tp> = __detail::__unique_ptr_t<main()::test>]’:
struct-pointer.cc:13:38:   required from here
   13 |     p = std::make_unique<struct test>("test");
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/usr/include/c++/14/bits/unique_ptr.h:1076:30: error: no matching function for call to ‘main()::test::test(const char [5])’
 1076 |     { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct-pointer.cc:6:12: note: candidate: ‘main()::test::test()’
    6 |     struct test
      |            ^~~~
struct-pointer.cc:6:12: note:   candidate expects 0 arguments, 1 provided
struct-pointer.cc:6:12: note: candidate: ‘main()::test::test(const main()::test&)’
struct-pointer.cc:6:12: note:   no known conversion for argument 1 from ‘const char [5]’ to ‘const main()::test&’
struct-pointer.cc:6:12: note: candidate: ‘main()::test::test(main()::test&&)’
struct-pointer.cc:6:12: note:   no known conversion for argument 1 from ‘const char [5]’ to ‘main()::test&&’

尝试无构造函数的结构体初始化:

struct test foo = { "test" };

这段代码能编译,但执行printf("%s\n", foo.s);时输出垃圾值而非"test"。

提出两个问题:

  1. 如何正确初始化结构体,使printf语句输出"test"?
  2. 使用std::unique_ptr而非局部变量时,如何初始化struct test?
解答

问题1:正确初始化结构体并输出"test"

垃圾值问题和结构体初始化无关,是printf使用错误导致的。printf的%s格式符需要接收C风格字符串(const char*),但你直接传递了std::string对象,这会让printf读取错误的内存地址,输出垃圾内容。

正确的处理方式有两种:

  • 用C++原生的std::cout输出,它支持直接打印std::string:
#include <iostream>
#include <string>

int main()
{
    struct test
    {
        std::string s;
    };

    struct test foo = { "test" }; // 聚合初始化本身是正确的
    std::cout << foo.s << std::endl;
}
  • 一定要用printf的话,调用std::string的c_str()方法获取C风格字符串指针:
#include <cstdio>
#include <string>

int main()
{
    struct test
    {
        std::string s;
    };

    struct test foo = { "test" };
    printf("%s\n", foo.s.c_str());
}

问题2:用std::unique_ptr初始化struct test

编译错误是因为std::make_unique会尝试调用test的构造函数,但你的结构体没有能接收const char*的构造函数,只有默认、拷贝、移动构造函数。

解决方法有两种:

方法一:给结构体加自定义构造函数

添加一个接收const char*的构造函数,让std::make_unique可以正确调用:

#include <cstdio>
#include <memory>
#include <string>

int main()
{
    struct test
    {
        std::string s;
        test(const char* str) : s(str) {}
    };

    std::unique_ptr<struct test> p = std::make_unique<struct test>("test");
    printf("%s\n", p->s.c_str());
}

方法二:用new配合聚合初始化

不想加构造函数的话,直接用new结合列表初始化创建对象,再交给unique_ptr管理:

#include <cstdio>
#include <memory>
#include <string>

int main()
{
    struct test
    {
        std::string s;
    };

    std::unique_ptr<struct test> p = std::unique_ptr<struct test>(new struct test{ "test" });
    // 更简洁的写法:auto p = std::unique_ptr<struct test>(new struct test{ "test" });
    printf("%s\n", p->s.c_str());
}

这种方式利用聚合类型的列表初始化特性,不需要自定义构造函数就能完成初始化。

内容的提问来源于stack exchange,提问作者user1785730

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:55:01