C++基底类别以衍生类别的成员初始化时发生警告“未初始化的字段”

jjhzyzn0  于 2022-12-01  发布在  其他
关注(0)|答案(2)|浏览(149)

我使用一个基类(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();
}
l7mqbcuq

l7mqbcuq1#

这 * 可能 * 如你所期望的那样工作,但是编译器警告不应该被忽略。mStorage在构造A的时候还不存在。基类首先被构造。也许编译器在查看mStorage时会提前查看,可以这么说,但是这不是所需的序列。mStorage可能只是随机的垃圾。
从框架中很难猜出其意图是什么,但通过创建一个返回指向派生类中存储的指针的虚函数,可以很容易地解决这个问题。您也可以找到某种模板解决方案。
我建议你多告诉我们一些你为什么要用这种方式设计类。
UPDATE:C++不知道N是什么是不高兴的,这是有充分理由的。当第(N +1)次调用worker_function时会发生什么?💥
我可以想到两种更安全的方法。一种是使append成为一个(纯)虚函数。无论如何,编写A::append并不容易,更不用说避免范围错误了。另一种是在类A中使用std::vector而不是std::array,而不尝试这种花哨的派生方案。

gdrx4gfi

gdrx4gfi2#

您可以使用组合而不是继承,并按正确的顺序放置类。
请注意,我不得不对你的constness做一些摆弄,才能让它真正起作用。
此处为在线示例。

#include <array>
#include <cstddef>

class A
{
public:
    explicit A(int* p, size_t s)
        : mPtr(p), mSize(s)
    {}

    void append(int i) { mPtr[i] = i; ++i; } // My guess

private:
    int*   mPtr  = nullptr;
    size_t mSize = 0;
};

template <size_t N>
class B
{
public:
    explicit B() : m_a(mStorage.data(), N) {}

    operator A&() {
        return m_a;
    }

private:
    std::array<int, N> mStorage {};
    A m_a;
};

void worker_function(A& a)
{
    a.append(int(1));
}

// and also

struct Foo
{
    Foo(A& a) : m_a(a) {}

    void do_some_work()
    {
         m_a.append(int(1));
    }

    A& m_a;
}; 

int main()
{
    B<10> b;
    worker_function(b);
    // and also
    Foo foo(b);
    foo.do_some_work();
}

相关问题