I notice that the Apache Arrow C++ libraries frequently define non-inline virtual destructors in code modules. Is there guidance for which classes should/should not have an explicitly defined non-inline destructor? For example, RandomAccessFile
contains a destructor declaration in arrow/io/interfaces.h:
class ARROW_EXPORT RandomAccessFile : public InputStream, public Seekable {
...
/// Necessary because we hold a std::unique_ptr
~RandomAccessFile() override;
...
};
and a corresponding definition in arrow/io/interfaces.cc:
RandomAccessFile::~RandomAccessFile() = default;
But BufferReader
has no such explicit declaration nor definition. I haven't been able to find any general C++ guidance for when a default destructor should be explicitly declared or defined, or for the tradeoffs between defining them inline or in the code module, and would like to better understand the tradeoffs.
I suspect that this lack of an explicit destructor on BufferReader
is causing linker warnings in my usage of Arrow, and I'm wondering if this is the cause. Specifically, I'm seeing:
INFO: From Linking ...:
/usr/bin/ld.gold: warning: while linking bazel-out/k8-fastbuild/bin/...: symbol 'virtual thunk to arrow::io::BufferReader::~BufferReader()' defined in multiple places (possible ODR violation):
/usr/include/c++/7/bits/shared_ptr_base.h:170 from bazel-out/k8-fastbuild/bin/external/arrow/_objs/arrow/function_internal.pic.o
external/arrow/cpp/src/arrow/io/memory.h:145 from bazel-out/k8-fastbuild/bin/external/arrow/_objs/parquet/0/schema.pic.o