在没有composite/decorator的情况下,在父类之前初始化子类

Initialize child class before parent class without composition / decorator

本文关键字:父类 子类 初始化 composite decorator 情况下      更新时间:2024-09-22

我需要再次做这样的事情-
我需要首先初始化向量,所以我将其数据((地址传递给父类。

#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("%dn", b.a == b.v.data() );
printf("%dn", b.a[55]);
printf("%dn", b.v[55]);
}

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

我知道我可以为这个或受保护的成员setPtr(int *a)使用composite/decorator,但我想知道是否有其他方法可以做到这一点

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

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

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("%dn", b.a == b.v.data() );
printf("%dn", b.a[55]);
printf("%dn", b.v[55]);
}

另外,为什么在C++中使用printf?这相当不安全。请改用std::cout。与人们普遍认为的相反,如果你处理得好,它实际上并不比C stdio慢多少,而且我们不确定I/O速度是否会成为你的代码的问题。

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

#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];
}

我选择了奇怪的重复出现的模板模式

#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("%dn", b.raw_ptr == b.v.data() );
printf("%dn", b.raw_ptr[55]);
printf("%dn", b.v[55]);
return 0;
}