关于初始化C ++中的成员变量,我有两个问题。


为什么将explicit Apple(const char* name) :Fruits(&_name)的构造函数定义为Fruits(或者将这些代码中的指针替换为引用)时,代码explicit Fruits(std::string* f_n) :f_name_(f_n)为何起作用?
派生类的成员变量是在其子基类的成员变量之后还是之前分配内存的?


请参见下面的代码。

// 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;
}

最佳答案

为什么将Fruits的构造函数定义为显式Fruits(std :: string * f_n):f_name_(f_n)(或这些代码中的指针)时,代码显式Apple(const char * name):Fruits(&_ name)为何起作用替换为参考)?


您传递类型为_name的成员变量std::string的地址,因此可以很好地进行编译,并且explicit与此无关。请注意,您在此处玩非常危险的游戏,如果尝试在Fruits的构造函数中取消引用该指针,则会得到UB。


  派生类的成员变量是在其子基类的成员变量之后还是之前分配内存的?


您的问题表明您不了解其工作原理。派生类是驻留在sizeof(typename)内存中的对象,该对象包括基础对象和派生添加的所有成员变量(如果有)。当为它分配内存时,它一次分配给整个对象,而不是部分分配。不同的问题是初始化的顺序-尽管分配了内存,但对象是从基类初始化为派生的,因此,如果您尝试在基类构造函数中访问派生类的对象,则会像尝试访问未初始化的对象一样获得UB。

关于c++ - 为什么C++可以使用未初始化的成员变量(引用或指针* NOT值拷贝*)来初始化其父类的成员变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50045162/

10-09 18:42