如果对象是堆栈创建的(包括继承的类型),是否可以发出编译错误
Is it possible to issue compile error if object is stack created (including inherited types)?
基本上,我希望通过工厂方法创建所有子类型(我有一个高大的域层次结构,其中包含大约 200+ 个类)。
对于new
,这不是问题,因为这可以在A中被覆盖(使new
私有)。
class A{
protected:
A();
public:
template<class T, typename... ARGUMENTS>
static T* create(ARGUMENTS&&... arguments);
};
class B : public A {
public:
B();
};
void test() {
B b;//compile error wanted here - but as a consequence of inheriting A
}
这里 A 是"库/框架"类,而 B 是"用户创建的类"。在 B 上要求 typedef 或类似的东西可能是可以的。
更新:我在 A 上添加了"创建"功能,我打算用于创建对象。
您可以在构造
A
中要求仅在A::create
正文中传递的令牌
#include <utility>
class A{
private:
struct create_token
{
create_token(const create_token &) = delete;
create_token& operator=(const create_token &) = delete;
create_token(create_token &&) = default;
create_token& operator=(create_token &&) = default;
};
protected:
A(create_token) {}
public:
template<class T, typename... ARGUMENTS>
static T* create(ARGUMENTS&&... arguments)
{
// Whatever creation mechanism here
return new T(create_token{}, std::forward<ARGUMENTS>(arguments)...);
}
};
class B : public A {
public:
template <typename Token> // Can't name A::create_token, it is private
B(Token tok) : A(std::move(tok)) {}
B(){} // Will always lack a `create_token`
};
int main() {
B b;//compile error wanted here - but as a consequence of inheriting A
B* b = A::create<B>();
}
现场观看
这是另一种依赖于检查派生类构造函数是否私有的方法。但老实说,我更喜欢@Caleth给出的解决方案
#include <type_traits>
#include <iostream>
#include <type_traits>
template<typename T, typename... Args>
struct constructor_tag{};
class A{
protected:
template<typename T, typename... Args>
A(constructor_tag<T, Args...>) {
static_assert(!std::is_constructible_v<T, Args...>, "CONSTRUCTOR MUST NOT BE PUBLIC");
};
public:
template<class T, typename... ARGUMENTS>
static T* create(ARGUMENTS&&... arguments) {
return new T(std::forward<ARGUMENTS>(arguments)...);
}
};
class B : public A {
friend class A;
B() : A(constructor_tag<B>{}) {}
public:
};
class C : public A {
friend class A;
C () : A(constructor_tag<C>{}) {}
C(int) : A(constructor_tag<C, int>{}) {}
public:
};
// Following class will not compile because the constructor is public
//class D : public A {
// friend class A;
//
//public:
// D () : A(constructor_tag<D>{}) {}
//
//};
void test() {
// B b; //calling a private constructor of class 'B'
// C c(5);//calling a private constructor of class 'A'
A::create<B>();
A::create<C>(5);
A::create<C>();
}
int main() {
test();
}
相关文章:
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 将错误返回给调用方而不是立即在 C++ 中抛出错误是否是一种好的做法
- 错误:在尝试检测 std::cout 是否<< t 时,功能强制转换为数组类型;有效
- 检查 n2 是否是 n1 的倍数后结果错误,但根本没有错误
- 使用 SET(C++) 检查两个给定字符串是否是字谜时出现运行时错误
- 我的代码中是否有任何类型的错误,因为它没有给出正确的输出
- C++ LeetCode #377 的 DP 解决方案中,此代码是否有错误?
- GCC 编译器是否应该对涉及 [[fallthrough]] 属性的格式错误的C++代码进行诊断?
- 以下 OpenCV 源代码中是否存在错误?(#ifdef 没有 #else)
- 是否与赢得64位有关?错误:STATUS_ACCESS_VIOLATION
- 对逻辑使用std::out_of_range是否错误
- gcc 在这个概念定义中是否错误地评估了 std::d eclval ?
- C++ - 我是否错误地使用了fin.ignore()?
- 我是否错误地使用Xcode或错误地编写了该程序
- 我是否错误地使用了默认参数
- 我是否错误地使用了 ncurses 库中的 getch() 函数
- C++我是否错误地使用了void函数
- 我是否错误地使用了布尔运算符
- MSVC 是否错误地处理了类范围的静态与整数常量初始值设定项的链接
- 我是否错误地使用了Windows剪贴板?