微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在没有组合/装饰器的情况下,在父类之前初始化子类

如何解决在没有组合/装饰器的情况下,在父类之前初始化子类

我再次需要做这样的事情-
我需要先初始化向量,然后将其data()地址传递给父类

#include <vector>

struct A{
    A(int *a) : a(a){}
    
    int *a;
};

struct B : A{
    B() : A( v.data() ){}
    
    std::vector<int> v { 1024 };
};

#include <cstdio>

int main(){
    B b;
    b.v[55] = 5;

    printf("%d\n",b.a == b.v.data() );
    printf("%d\n",b.a[55]);
    printf("%d\n",b.v[55]);
}

这里的问题是向量在父类之后初始化并且v.data()包含垃圾。我什至对此编译感到惊讶。

我知道我可以为此或受保护的成员setPtr(int *a)使用组合/装饰器,但是我想知道是否还有另一种方法

请不要对原始指针发表评论。这只是父类和子类之间依赖关系的一个示例。

解决方法

首先通过设计构造基类。没办法。但是,您可以引入第二个基类,并以所需的初始化顺序从基类继承。

struct a
{
    int x;
    a(int x) : x(x) {};
};

struct b
{
    int *px;
    b(int* px) : px(px) {};
};

struct derived : a,b
{
public:
    derived(int x_) : a(x_),b(&x) {};
};
,

为什么不将A的初始化委派给构造函数以外的其他函数?

#include <vector>

struct A{
    A() : a(nullptr) {}
    void init(int* i_a) {
        a = i_a;
    }
    
    int *a;
};

struct B : A{
    B() : A(),v(1024) {
        init(v.data());
    }
    
    std::vector<int> v;
};

#include <cstdio>

int main(){
    B b;
    b.v[55] = 5;

    printf("%d\n",b.a == b.v.data() );
    printf("%d\n",b.a[55]);
    printf("%d\n",b.v[55]);
}

此外,为什么在C ++中使用printf?这是相当不安全的。请改用std::cout。与通常的看法相反,如果处理得当,它实际上没有比C stdio慢多少,而且我们不确定I / O速度甚至对您的代码来说都是问题。

,

不建议将其作为解决方案,但可能会提示实际解决方案。您不能在基类构造函数中使用派生类的成员。但是,您可以在构造基础时使用对派生成员的引用或指针。您只需要注意在完全构造派生对象之后才取消引用它们。例如,这是“确定”:

#include <vector>
#include <iostream>

struct A{
    A(std::vector<int>* p) : p(p){}
    std::vector<int>* p;
};

struct B : A{
    B() : A( &v ){} // <- fine as long as A only stores the pointer
    std::vector<int> v { 1024 };
};

int main(){
    B b;
    b.v[55] = 5;
    std::cout << (b.p == &b.v) << "\n";
    std::cout << (*b.p)[55];
}
,

我去了curiously recurring template pattern

#include <iostream>
#include <vector>
#include <stdio.h>

template <typename T>
struct Base {
  int* raw_ptr = nullptr;   
  void Supply() {
    (static_cast<T*>(this))->Supply();
  }
};

struct Derived : public Base<Derived> {
  std::vector<int> v { 1024 }; 
  void Supply() {
    raw_ptr = v.data();
  }
};


template<typename T>
void SupplyBuffer(Base<T>* b) {
  b->Supply();
}

int main()
{
    Derived b;
    SupplyBuffer(&b);
    b.v[55] = 5;    
    printf("%d\n",b.raw_ptr == b.v.data() );
    printf("%d\n",b.raw_ptr[55]);
    printf("%d\n",b.v[55]);
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。