c++:接口强制copy-constr定义
C++: Interface enforcing definition of copy-constr
接口类是否有办法强制定义复制构造函数和其他构造函数?在我的例子中,我有一个IResource
纯抽象类,我希望实现这个接口的所有类都定义一个复制构造函数,一个用于从文件加载的构造函数,以及一个用于从内存加载的构造函数。
为了构造一个对象,您需要知道要使用的具体类(否则它如何知道要分配多少内存,或者使用哪个虚拟表,等等?)因此,在处理构造函数时,接口不起作用,并且不能使用接口(纯虚函数)来强制存在这样的构造函数。当你想到它时,这是很自然的,虚拟只有在你有一个多态对象时才能工作,即在实例化之后。任何引用你的IResource接口的人都只会处理实例化的对象,而永远不会触及构造函数。
如果你想的话,你可以使用模板来强制这些约束。通过简单地从模板化函数中调用复制构造函数,如果遇到使用没有复制构造函数的类型的模板实例化,编译器将会报错。
你不能强制执行,这也不是一个正确的方法。相反,应该防止在多态类层次结构中使用公共复制构造函数…
struct IResource {
virtual IResource* Clone() const = 0;
virtual ~IResource() {}
};
IResource
的实现者应该遵循以下模式:
class ConcreteResource : public IResource, public boost::noncopyable { // or equivalent
public:
virtual ConcreteResource* Clone() const;
explicit ConcreteResource(std::string const & pString) : mString(pString) {}
private:
std::string mString;
};
ConcreteResource* ConcreteResource::Clone() const {
return new ConcreteResource(this->mString);
}
在您的项目中使用IResource
抽象类,不知怎的,我怀疑它要求它使用的对象包含特定的构造函数。
其他创建 IResource
对象(可能很多东西),并且必须使用构造函数。创建的具体类必须实现必要的构造函数,否则代码将无法编译。
您可以像这样将所有需求推送到资源实现中:
class t_resource_interface {
protected:
virtual ~t_resource_interface();
public:
virtual t_serialization* serializeResource() = 0;
virtual t_thing* cloneResource() = 0;
};
/* type disambiguators */
typedef enum t_load_from_url { LoadFromURL = 0 } t_load_from_url;
typedef enum t_load_from_memory { LoadFromMemory = 0 } t_load_from_memory;
typedef enum t_copy_constructor { CopyConstructor = 0 } t_copy_constructor;
template < typename TResourceImplementation >
class t_resource : public t_resource_interface {
public:
/* copy ctor should generally be avoided due to the expense. introduce a parameter for those cases where it's really needed and disable the standard copy ctor */
t_resource(const t_copy_constructor& copyCtor, const t_resource& other) : t_resource_interface(), d_implementation(TResourceImplementation::CopyConstructor(other.d_implementation)) {
MONUnusedParameter(copyCtor);
}
t_resource(const t_load_from_url& fromFile, const t_url& url) : t_resource_interface(), d_implementation(TResourceImplementation::LoadFromURL(url)) {
MONUnusedParameter(fromFile);
}
t_resource(const t_load_from_memory& fromMemory, const t_serialization& serialization) : t_resource_interface(), d_implementation(TResourceImplementation::LoadFromMemory(serialization)) {
MONUnusedParameter(fromMemory);
}
virtual ~t_resource() {
}
public:
/* t_resource_interface requirements. implementation forwarded to TResourceImplementation */
virtual t_serialization* serializeResource() {
return this->d_implementation->serializeResource();
}
virtual t_thing* cloneResource() {
return this->d_implementation->cloneResource();
}
private:
/* assuming you will end up needing dynamic allocation/polymorphism along the way... */
t_auto_pointer<TResourceImplementation> d_implementation;
private:
/* prohibited */
t_resource(const t_resource&);
t_resource& operator=(const t_resource&);
};
class t_image_resource_implementation : public t_resource_interface {
private:
static t_image_resource_implementation* ValidationCheck(const t_image_resource_implementation* const arg) {
assert(arg && "allocation or argument error");
if (0 == arg) {
return 0;
}
else if (0 == arg->isValid()) {
delete res;
return 0;
}
else {
return arg;
}
}
public:
static t_image_resource_implementation* CopyConstructor(const t_image_resource_implementation* const other) {
return ValidationCheck(new t_image_resource_implementation(other, ...));
}
static t_image_resource_implementation* LoadFromURL(const t_url& url) {
/* assuming t_image_at_url_resource_implementation exists */
return ValidationCheck(new t_image_at_url_resource_implementation(url, ...));
}
static t_image_resource_implementation* LoadFromMemory(const t_serialization& serialization) {
assert(serialization);
if (0 == serialization) {
return 0;
}
else {
return ValidationCheck(new t_image_resource_implementation(serialization, ...));
}
}
/* some physical ctors and the rest of the implementation... */
public:
/* t_resource_interface requirements */
virtual t_serialization* serializeResource() {
return this->createSerialization();
}
virtual t_thing* cloneResource() {
return this->clone();
}
};
typedef t_resource<t_image_resource_implementation> t_image_resource;
t_error_code ConvertImageToGrayscale(const t_url& sourceUrl, const t_url& destinationUrl) {
t_image_resource imageResource(LoadFromURL, sourceUrl);
/* ... */
}
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 部分定义/别名模板模板参数
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- #为""定义宏;静态";针对不同的上下文
- 如何确保C++函数在定义之前声明(如override关键字)
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在命名空间中定义函数还是限定函数
- 此代码是否违反一个定义规则
- 编译C++时未定义的引用
- 不同翻译单元中不可重载的非内联函数定义
- 为什么在定义函数之前先声明它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- MSVC++ 17 std::copy 期望自定义迭代器的"operator -"
- 如何使用 std::copy 打印用户定义的类型
- 在 CMake for Visual Studio 2010 中定义宏"disallow copy and assign"
- std::copy的自定义插入器
- c++:接口强制copy-constr定义