为什么C++可以使用未初始化的成员变量(引用或指针 *NOT 值复制*)来初始化其父类的成员变量
Why can C++ use the uninitialized member variables (reference or pointer *NOT value copy*) to initialize the member variables of its parent class
我有两个关于在C++中初始化成员变量的问题。
-
为什么当
Fruits
的构造函数定义为explicit Fruits(std::string* f_n) :f_name_(f_n)
时(或者当这些代码中的指针被替换为引用时),代码explicit Apple(const char* name) :Fruits(&_name)
工作?
派生类的成员变量 是在其子基类的成员变量之后还是之前分配内存?
请参阅下面的代码。
// Apple.h c++
#pragma once
#include<iostream>
#include<cstring>
#include<string>
class Plant {
public:
Plant() {
std::cout << "Plant construction function called." << std::endl;
}
inline void show() {
std::cout << "name:" << s_name_ << std::endl;
}
void Init() {
std::cout << "Init assign value called." << std::endl;
s_name_ = this->getName();
}
virtual ~Plant() {
std::cout << "Plant deconstruction function called." << std::endl;
}
private:
std::string s_name_;
protected:
virtual std::string getName() = 0;
};
class Fruits: public Plant{
public:
explicit Fruits(std::string* f_n) :f_name_(f_n) {
std::cout << "Fruits construction function called."<< std::endl;
}
virtual ~Fruits() {
std::cout << "Fruits deconstruction function called." << std::endl;
}
protected:
std::string getName() override {
std::cout << "getName() function called." << std::endl;
return *f_name_;
}
private:
std::string* f_name_;
};
class Apple:public Fruits {
private:
std::string _name;
public:
explicit Apple(const char* name) :Fruits(&_name) {
_name = name;
std::cout << "Apple constuction function called."<< std::endl;
Plant::Init();
}
~Apple() {
std::cout << "Apple deconstruction function called." << std::endl;
}
};
// main.cpp
#include<iostream>
#include "Apple.h"
using namespace std;
int main() {
{
cout << "test1:" << endl;
Apple t1("Apple1");
t1.show();
}
cin.get();
return 0;
}
为什么当 Fruit 的构造函数定义为显式 Fruits(std::string* f_n) :f_name_(f_n) 时,代码显式 Apple(const char* name) :Fruits(&_name) 起作用?
您将成员变量的地址传递_name
,该变量的类型为std::string
,因此它可以很好地编译,并且explicit
与此无关。请注意,您在这里玩非常危险的游戏,如果您尝试在构造函数中取消引用该指针Fruits
您将获得 UB。
是在其子基类的成员变量之后还是之前分配内存?
您的问题表明您不了解它是如何工作的。派生类是驻留在内存sizeof(typename)
的对象,内存包括基对象和派生添加的所有成员变量(如果有)。当为它分配内存时,它会立即分配给整个对象,而不是按它的一部分分配。不同的问题是初始化的顺序 - 虽然内存分配的对象是从基初始化到派生的,所以如果你尝试访问基类构造函数中派生类的对象,你会得到UB,就像你会尝试访问未初始化的对象一样。
因为它只是向Apple添加一个具有不同签名的构造函数。这与水果无关。
1.为什么代码显式 Apple(const char* name) :水果(&_name) 当水果的构造函数定义为显式时工作 水果(std::string* f_n) :f_name_(f_n) (或当这些中的指针 代码替换为参考)?
您的explicit Fruits(std::string* f_n)
需要 std::string 上的指针_name
是 std::string 类型的 Apple 成员,因此采用_name
地址将转换为所需的 std::string*。
派生类的成员变量
- 是在其子基类的成员变量之后还是之前分配内存?
首先初始化父类,在该派生类之后。 所以在你的情况下,在这里传递Fruits(&_name)
:
explicit Apple(const char* name) :Fruits(&_name) {
_name = name;
表示此时_name未初始化,将在 Fruit 构造函数完成后进行初始化
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 将包含C样式数组的对象初始化为成员变量(C++)
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在循环中按顺序遍历成员变量
- c++类声明时,相同的例程,不同的成员变量类型
- 如何从另一个文件继承私有成员变量和公共函数
- 在C++类中,是否必须初始化作为数组的成员变量
- 如何从子成员函数修改父公共成员变量
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 打印所有继承的类成员变量和方法
- 如何在复杂继承中访问静态成员变量
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 成员变量与函数概念检查