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

为何传递指针调用Json::Value::append能通过编译?

为什么带new的Json::Value::append能编译通过,而自定义示例不行?

昨天在团队代码里发现一段使用jsoncpp库的函数:

#include <json/value.h>

Json::Value makeList() {
  Json::Value list(Json::arrayValue);
  list.append(new Json::Value(true));
  return list;
}

这段代码因为在append调用中使用new存在内存泄漏,去掉new即可修复。但查看Json::Value::append的参数要求,它仅接受const Json::Value&或Json::Value&&类型,而C++不会自动将指针隐式转换为引用,按此逻辑Json::Value*本应无法匹配参数类型才对。

为验证这个逻辑,我编写了一个简单的测试示例:

#include <iostream>

class Foo {
public:
    int x = 4;
};

void printValue(const Foo& f) { std::cout << "The value is " << f.x << ".\n"; }
void printValue(Foo&& f)      { std::cout << "The value is " << f.x << ".\n"; }

int main() {
    printValue(new Foo());
}

该示例确实出现编译错误,错误信息如下:

own-example.cpp:12:5: error: no matching function for call to 'printValue'
    printValue(new Foo());
    ^~~~~~~~~~
own-example.cpp:8:6: note: candidate function not viable: no known conversion from 'Foo *' to 'const Foo' for 1st argument; dereference the argument with *
void printValue(const Foo& f) { std::cout << "The value is " << f.x << ".\n"; }
     ^
own-example.cpp:9:6: note: candidate function not viable: no known conversion from 'Foo *' to 'Foo' for 1st argument; dereference the argument with *
void printValue(Foo&& f)      { std::cout << "The value is " << f.x << ".\n"; }
     ^

那为什么调用Json::Value::append的代码能通过编译,而我写的示例却不能?


原因分析

问题的核心在于jsoncpp的Json::Value类定义了一个非explicit的构造函数,允许从Json::Value*隐式转换为Json::Value对象。

具体来说,Json::Value存在类似这样的构造函数签名:

Value( Value* other ); // 非explicit修饰

当你调用list.append(new Json::Value(true))时,编译器会完成两步隐式转换:

  1. 将new返回的Json::Value*指针,通过上述构造函数隐式转换为一个临时的Json::Value对象;
  2. 这个临时对象会匹配append的Json::Value&&(右值引用)参数,从而顺利完成函数调用。

而你自定义的Foo类没有定义接受Foo*的构造函数,编译器找不到合法的转换路径,因此触发编译错误。

另外要注意,这种隐式转换正是内存泄漏的根源:临时Json::Value对象会复制指针指向的内容,之后原指针指向的堆内存无人释放,最终造成泄漏。去掉new直接传递Json::Value(true)临时对象,就能避免这个问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:22:45