Dig*_*Man 0 c++ inheritance constructor
我有一个设计为通用的类,在任何地方使用,看起来有点像这样:
class FixedByteStream {
public:
FixedByteStream(const char* source)
{
size = strlen(source);
copy(source);
}
/* Many more constructors here */
protected:
void copy(const char* source)
{
address = allocate();
//...
}
/* Plus other functions that call allocate() */
char* FixedByteStream::allocate()
{
return (char*)malloc(size);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我扩展了这个类,以便它可以使用特定于项目的内存池.
class PooledByteStream : public FixedByteStream {
public:
PooledByteStream::PooledByteStream() : FixedByteStream() {}
protected:
char* PooledByteStream::allocate()
{
return (char*)PooledByteStream::pool.allocate(size);
}
}
Run Code Online (Sandbox Code Playgroud)
PooledByteStream应该与 FixedByteStream 相同,具有所有相同的函数和构造函数,除了调用allocate()时,它应该从内存池中检索指针.
但是,从未调用过 PooledByteStream :: allocate().不是来自继承的构造函数,也不来自其他继承的函数(调用继承的copy()).从基类继承的任何东西都完全没有注意到allocate()应该做一些完全不同的事情.
问题是,我该如何解决这个问题?如何使继承函数调用重写函数,而不是基类函数?从基类复制粘贴所有必要的函数会抹掉继承点,所以我假设这不是答案.
注意:我不是在寻找有关内存管理或其他方法的建议,以达到相同的最终结果.这只是一个例子!
您需要声明allocate()为虚拟以覆盖它.但是,基类构造函数不能调用派生类的重写,因为派生类尚未构造,并且基类析构函数无法调用派生类的重写,因为派生类已经被破坏.
如果必须调用allocate()基类构造函数,则可以使用模板来绕过限制,例如:
template<typename Derived>
class FixedByteStreamBase
{
public:
FixedByteStreamBase(const char* source)
{
size = strlen(source);
copy(source);
}
/* Many more constructors here */
protected:
void copy(const char* source)
{
address = Derived::allocate();
//...
}
/* Plus other functions that call allocate() */
};
class FixedByteStream : public FixedByteStreamBase<FixedByteStream>
{
public:
static char* allocate()
{
return (char*)malloc(size);
}
};
class PooledByteStream : public FixedByteStreamBase<PooledByteStream>
{
public:
static char* allocate()
{
return (char*)pool.malloc(size);
}
};
Run Code Online (Sandbox Code Playgroud)
要么:
struct MallocAllocator
{
static char* allocate()
{
return (char*)malloc(size);
}
};
struct PoolAllocator
{
static char* allocate()
{
return (char*)pool.allocate(size);
}
};
template<typename Allocator>
class FixedByteStreamBase {
public:
FixedByteStreamBase(const char* source)
{
size = strlen(source);
copy(source);
}
/* Many more constructors here */
protected:
void copy(const char* source)
{
address = Allocator::allocate();
//...
}
/* Plus other functions that call allocate() */
};
typedef FixedByteStreamBase<MallocAllocator> FixedByteStream;
typedef FixedByteStreamBase<PoolAllocator> PooledByteStream;
Run Code Online (Sandbox Code Playgroud)