MemRef 是一个简单的类,指向它不拥有的一些内存。
基类:
class MemRef {
protected:
const char * _ptr;
std::size_t _len;
public:
// Constructors
MemRef() : _ptr(0), _len(0) {}
MemRef(const string& s) : _ptr(s.c_str()), _len(s.length()) {}
MemRef(const char* b, size_t l) : _ptr(b), _len(l) {}
};
Loaded_MemRef 是一个子类,它提供自己的缓冲区,当不能信任调用者提供在 MemRef 的生命周期内保持分配和未更改的内存时。 Loaded_MemRef 将数据复制到它控制的秘密缓冲区中,然后指向它,允许我将其视为简单的 MemRef 。
派生类:
class Loaded_MemRef : public MemRef {
private:
const string _memory;
public:
Loaded_MemRef(const string& s) : ??? {}
Loaded_MemRef(const char*);
Loaded_MemRef(const char*, const size_t);
};
我在为 Loaded_MemRef 创建ctors时遇到问题。在调用 MemRef 的ctor之前,我必须将 _memory 复制到调用者提供首先的内存中;否则 MemRef 无法检索有效的 _memory.c_str()。但我的理解是,在初始化 Loaded_MemRef 的成员之前,必须首先调用 MemRef(_memory)。所以我尝试了这个:
Loaded_MemRef(const string& str) :
MemRef(), // get this over with
_memory(str), // copy str into _memory
MemRef::_ptr(_memory.c_str()), // (LINE 108) "reach up into" MemRef and set its protected members
MemRef::_len(_memory.length())
{}
抱怨:
MemRef.cpp: In constructor 'Loaded_MemRef::Loaded_MemRef(const std::string&)':
MemRef.cpp:108: error: expected class-name before '(' token
MemRef.cpp:108: error: expected '{' before '(' token
(第108行显示在上面;下一行,设置 _len ,不会被标记,尽管编译器可能会被保释。)
正确的方法是什么?
答案 0 :(得分:2)
你真的不需要在初始化器中设置东西。你可以在构造函数的主体中完成它:
Loaded_MemRef(const string& str) :
MemRef(), // get this over with
_memory(str), // copy str into _memory
{
_ptr = _memory.c_str();
_len = _memory.length();
}
如果你的基类有const size_t _len
,就不可能实现你想要的,因为const
成员需要初始化器,而C ++强制要求的初始化顺序与你需要的相反。
答案 1 :(得分:2)
您可以从_ptr
构造函数的正文中更改_len
和Loaded_MemRef
(因为它们是protected
)。
你可以给MemRef
一个(protected
?)成员函数来改变它所指向的位置,并使用Loaded_MemRef
构造函数体中的那个。
或者,如果你真的,真的想/需要初始化MemRef
一次,你可以将string
移动到在基类之前初始化的那一件事:另一个基类(声明virtual
或更早版本。
仅使用C ++ 03:
struct Loaded_MemRef__Base
{
std::string _memory;
explicit Loaded_MemRef__Base(const std::string& str)
: _memory(str) {}
};
class Loaded_MemRef
: private Loaded_MemRef__Base,
public MemRef
{
public:
Loaded_MemRef(const string& str) :
Loaded_MemRef__Base( str ),
MemRef( _memory.data(), _memory.length() )
{}
};
使用C ++ 11功能:
struct Loaded_MemRef__Base
{
std::string _memory;
};
class Loaded_MemRef
: private Loaded_MemRef__Base,
public MemRef
{
public:
Loaded_MemRef(std::string str) :
Loaded_MemRef__Base{ std::move(str) },
MemRef( _memory.data(), _memory.length() )
{}
};
答案 2 :(得分:1)
您无法在派生类初始化列表中初始化超类的成员,即使它们受到保护。解决方案是使用超类的构造函数。