我使用一个基类(A)来管理一些数据,但没有存储空间。派生类(B)有一个存储成员,并使用指向该存储空间的指针和它们的大小来初始化基类(A)。
IDE中的代码模型(clang)在explicit B() : A(mStorage.data(), 10) {}
行发出警告“Field mStorage is uninitialized when used here”(在此处使用时未初始化字段mStorage)
问题1:只要我不使用基类构造函数中的存储,这是否是一个问题?
问题2:如果这不会导致问题,是否有办法避免此警告?
class A
{
public:
explicit A(int* p, size_t s)
: mPtr(p), mSize(s)
{}
void append(int i) { /* ... */ }
private:
int* mPtr = nullptr;
size_t mSize = 0;
};
template <size_t N>
class B : public A
{
public:
explicit B() : A(mStorage.data(), N) {}
private:
std::array<int, N> mStorage {};
};
更新:
- 将模板添加到B类
- 我的意图是将类的正常使用和类B中的模板大小分离开来
void worker_function(const A& a)
{
a.append(int(1));
}
// and also
struct Foo
{
Foo(const A& a) : m_a(a) {}
void do_some_work()
{
a.append(int(1));
}
const A& m_a;
};
void main()
{
B<10> b;
worker_function(b);
// and also
Foo foo(b);
foo.do_some_work();
}
2条答案
按热度按时间l7mqbcuq1#
这 * 可能 * 如你所期望的那样工作,但是编译器警告不应该被忽略。
mStorage
在构造A的时候还不存在。基类首先被构造。也许编译器在查看mStorage
时会提前查看,可以这么说,但是这不是所需的序列。mStorage
可能只是随机的垃圾。从框架中很难猜出其意图是什么,但通过创建一个返回指向派生类中存储的指针的虚函数,可以很容易地解决这个问题。您也可以找到某种模板解决方案。
我建议你多告诉我们一些你为什么要用这种方式设计类。
UPDATE:C++不知道N是什么是不高兴的,这是有充分理由的。当第(N +1)次调用
worker_function
时会发生什么?💥我可以想到两种更安全的方法。一种是使
append
成为一个(纯)虚函数。无论如何,编写A::append
并不容易,更不用说避免范围错误了。另一种是在类A中使用std::vector
而不是std::array
,而不尝试这种花哨的派生方案。gdrx4gfi2#
您可以使用组合而不是继承,并按正确的顺序放置类。
请注意,我不得不对你的constness做一些摆弄,才能让它真正起作用。
此处为在线示例。