在C++库Gandiva中使用指向std::shared_ptr的指针的目的是什么?
Great question—this is a common point of confusion when working with factory-style APIs in C++ libraries like Gandiva. Let’s break down the reasoning behind this design choice:
Explicit Output Parameter Semantics
TheMakemethod is a factory function: its job is to create aFilterinstance and hand ownership back to the caller. Using a pointer to ashared_ptrmakes it crystal clear that this parameter is an output—the function will modify the value you pass in. While a non-const reference (std::shared_ptr<Filter>&) could achieve the same result, pointers are often used in such APIs to visually distinguish "input-only" parameters from "output" ones, making the code’s intent easier to parse at a glance.Avoiding Unnecessary Overhead
While copying ashared_ptris relatively cheap (it’s just an atomic increment of the reference count), using a pointer skips even that small cost entirely. For performance-critical APIs like those in Gandiva (focused on high-performance expression evaluation), minimizing any unnecessary operations can add up, especially with frequent calls.Consistency with Traditional C++ Library Patterns
Many low-level or performance-focused C++ libraries (including parts of Apache Arrow itself) stick to the classic "pointer as output parameter" pattern, which has been a standard way to return values from functions since C. This consistency helps maintain a uniform API style across the codebase, making it easier for developers familiar with other Arrow modules to pick up Gandiva.Null Safety and Parameter Validation
Unlike references, pointers can be null. This allows theMakefunction to explicitly check if the input pointer is valid (i.e., notnullptr) and return an appropriate error status if it isn’t. With a reference, you’d have no way to handle invalid inputs gracefully—passing an invalid reference would lead to undefined behavior, which is far harder to debug.
It’s important to note that this use of a "bare pointer" doesn’t contradict the purpose of shared_ptr: the pointer here isn’t managing memory—it’s just a way to pass the address of your shared_ptr to the function so it can populate it with the newly created object. The actual memory ownership is still safely handled by the shared_ptr itself.
Here’s how you’d typically use this API correctly:
std::shared_ptr<Filter> my_filter; Status s = Filter::Make(my_schema, my_condition, &my_filter); if (!s.ok()) { // Handle initialization error here }
内容的提问来源于stack exchange,提问作者Hua

