C++问题提问 有偿提问 求解答(希望有完整代码)

img

⚫ 写出类 Base、Inner、Top 三个类之间的关系
⚫ 给各个类添加构造函数/析构函数,并在函数中加入输出语句,使得对象生成和消亡时, 能做出相应的显示;在main( )函数各语句执行前或后,也加入相应的输出信息,方便 观察构造函数/析构函数执行情况。最后从运行结果中分析总结出 Top 类生成对象以及 对象撤销时,构造函数/析构函数的调用规律。
⚫ 在 Top 类中增加拷贝构造函数,比较 void fun1(Top t)和 void fun2(Top& t)调用时参数传 递的区别。
以上代码写在一个源文件中,从程序运行结果总结回答上面问题。


#include <iostream>

class Base
{
public:
    Base() { std::cout << "Base::Base()" << std::endl; }
    ~Base() { std::cout << "Base::~Base()" << std::endl; }
};

class Inner : public Base
{
public:
    Inner() { std::cout << "Inner::Inner()" << std::endl; }
    ~Inner() { std::cout << "Inner::~Inner()" << std::endl; }
};

class Top
{
public:
    Top() { std::cout << "Top::Top()" << std::endl; }
    Top(const Top& other) { std::cout << "Top::Top(const Top&)" << std::endl; }
    ~Top() { std::cout << "Top::~Top()" << std::endl; }

private:
    Inner m_inner;
};

void fun1(Top t)
{
    std::cout << "fun1()" << std::endl;
}

void fun2(Top& t)
{
    std::cout << "fun2()" << std::endl;
}

int main()
{
    std::cout << "Before creating t1" << std::endl;
    Top t1;
    std::cout << "After creating t1" << std::endl;

    std::cout << "Before calling fun1()" << std::endl;
    fun1(t1);
    std::cout << "After calling fun1()" << std::endl;

    std::cout << "Before calling fun2()" << std::endl;
    fun2(t1);
    std::cout << "After calling fun2()" << std::endl;

    return 0;
}

class ADT{
private:
int room;
public:
int hook;
// 构造函数
ADT(int r, int h) : room(r), hook(h) {}
// 声明友元函数
friend int getRoom(ADT &obj);
friend void setRoom(ADT &obj, int r);
friend int getHook(ADT &obj);
friend void setHook(ADT &obj, int h);
};
// 友元函数的定义
int getRoom(ADT &obj) { return obj.room; }
void setRoom(ADT &obj, int r) { obj.room = r; }
int getHook(ADT &obj) { return obj.hook; }
void setHook(ADT &obj, int h) { obj.hook = h; }
int main() {
  ADT obj(10, 20);
  // 使用友元函数访问数据成员
  cout << getRoom(obj) << endl;
  cout << getHook(obj) << endl;
  // 使用友元函数修改数据成员的值
  setRoom(obj, 100);
  setHook(obj, 200);
  cout << getRoom(obj) << endl;
  cout << getHook(obj) << endl;

  return 0;
}

#include <iostream>
using namespace std;

//基类
class Base
{
public:
    Base(){ cout<<"Base函数的构造: Base::Base()"<<endl; }
    virtual ~Base(){ cout<<"Base函数的析构: Base::~Base()"<<endl;  }
};
//派生类的子类
class Inner
{
public:
    Inner(){ cout<<"Inner函数的构造: Inner::Inner()"<<endl; }
    ~Inner(){ cout<<"Inner函数的析构: Inner::~Inner()"<<endl;  }
};
//派生类继承基类
class Top:public Base{
public:
    Top(){ cout<<"Top函数的无参构造: Top::Top()"<<endl; }
    ~Top(){ cout<<"Top函数的析构: Top::~Top()"<<endl; }
    
    //新增的拷贝构造
    Top(const Top& t){ cout<<"Top函数的引用(有参)构造"<<endl; (void)t; }
private:
    Inner pbln;
};
void fun1(Top t)
{
    cout<<"In fun1()"<<endl;
    (void)t;
}
void fun2(Top& t)
{
    cout<<"In fun2()"<<endl;
    (void)t;
}

int main()
{
    cout<<"=============================="<<endl;
    cout<<"1.类对象 t1 开始创建(根据创建规则,会先创建本对象的基类,再创建本对象的派生类,最后创建本对象)"<<endl;
    Top t1;
    cout<<"1.类对象 t1 创建成功"<<endl;
    cout<<"=============================="<<endl;

    cout<<"2.指针对象 pt 开始创建"<<endl;
    Top *pt;
    cout<<"2.指针对象 pt 创建成功"<<endl;
    cout<<"=============================="<<endl;

    cout<<"3.函数fun1开始运行..."<<endl;
    fun1(t1);
    cout<<"=============================="<<endl;
    cout<<"4.函数fun2开始运行..."<<endl;
    fun2(t1);
    cout<<"=============================="<<endl;
    
    cout<<"5.开始创建两个Top对象"<<endl;
    pt = new Top[2];
    cout<<"=============================="<<endl;

    cout<<"6.创建成功,开始销毁指针对象pt"<<endl;
    delete []pt;
    cout<<"=============================="<<endl;
    std::cout << "Hello world" << std::endl;
    return 0;
}
//1.写出类Base、Inner、Top 三个类之间的关系
//答:Base为Top的基类,Top为Inner的基类,三者为爷孙三代的关系!!!
//
//2.给各个类添加构造函数/析构函数,并在函数中加入输出语句,使得对象生成和消亡时,
//  能做出相应的显示;在main()函数各语句执行前或后,也加入相应的输出信息,方便观察
//  构造函数/析构函数执行情况。最后从运行结果中分析总结出Top类生成对象以及对象撤
//  销时,构造函数/析构函数的调用规律。
//答:根据执行情况可知,当Top类创建对象(调用构造函数,默认优先调用无参构造):
//          1.先创建Top类的基类,2.再创建Top类的派生类,3.最后创建Top类。
//    当销毁Top对象时(调用析构函数):
//          1.先销毁Top类,2.再销毁Top类的派生类,3.最后销毁Top类的基类
//
//3.在Top类中增加拷贝构造函数,比较void fun1(Top t)和 void fun2(Top& t) 调用时参
//  数传递的区别。以上代码写在一个源文件中,从程序运行结果总结回答上面问题。
//答:根据现象可知,如果没有有参(拷贝)构造时,Top t会调用无参构造,若有时,则会转为调用有参(拷贝)构造,
//    而Top &t本身便是传引用,不需要重新再调用构造函数。
==============================
1.类对象 t1 开始创建(根据创建规则,会先创建本对象的基类,再创建本对象的派生类,最后创建本对象)
Base函数的构造: Base::Base()
Inner函数的构造: Inner::Inner()
Top函数的无参构造: Top::Top()
1.类对象 t1 创建成功
==============================
2.指针对象 pt 开始创建
2.指针对象 pt 创建成功
==============================
3.函数fun1开始运行...
Base函数的构造: Base::Base()
Inner函数的构造: Inner::Inner()
Top函数的引用(有参)构造
In fun1()
Top函数的析构: Top::~Top()
Inner函数的析构: Inner::~Inner()
Base函数的析构: Base::~Base()
==============================
4.函数fun2开始运行...
In fun2()
==============================
5.开始创建两个Top对象
Base函数的构造: Base::Base()
Inner函数的构造: Inner::Inner()
Top函数的无参构造: Top::Top()
Base函数的构造: Base::Base()
Inner函数的构造: Inner::Inner()
Top函数的无参构造: Top::Top()
==============================
6.创建成功,开始销毁指针对象pt
Top函数的析构: Top::~Top()
Inner函数的析构: Inner::~Inner()
Base函数的析构: Base::~Base()
Top函数的析构: Top::~Top()
Inner函数的析构: Inner::~Inner()
Base函数的析构: Base::~Base()
==============================
Hello world
Top函数的析构: Top::~Top()
Inner函数的析构: Inner::~Inner()
Base函数的析构: Base::~Base()



#include <iostream>
class Base
{
public:
    Base() { std::cout << "Base::Base()" << std::endl; }
    ~Base() { std::cout << "Base::~Base()" << std::endl; }
};
class Inner : public Base
{
public:
    Inner() { std::cout << "Inner::Inner()" << std::endl; }
    ~Inner() { std::cout << "Inner::~Inner()" << std::endl; }
};
class Top
{
public:
    Top() { std::cout << "Top::Top()" << std::endl; }
    Top(const Top& other) { std::cout << "Top::Top(const Top&)" << std::endl; }
    ~Top() { std::cout << "Top::~Top()" << std::endl; }
private:
    Inner m_inner;
};
void fun1(Top t)
{
    std::cout << "fun1()" << std::endl;
}
void fun2(Top& t)
{
    std::cout << "fun2()" << std::endl;
}
int main()
{
    std::cout << "Before creating t1" << std::endl;
    Top t1;
    std::cout << "After creating t1" << std::endl;
    std::cout << "Before calling fun1()" << std::endl;
    fun1(t1);
    std::cout << "After calling fun1()" << std::endl;
    std::cout << "Before calling fun2()" << std::endl;
    fun2(t1);
    std::cout << "After calling fun2()" << std::endl;
    return 0;
}

```c#


```

#include <iostream>
class Base
{
public:
    Base() { std::cout << "Base::Base()" << std::endl; }
    ~Base() { std::cout << "Base::~Base()" << std::endl; }
};
class Inner : public Base
{
public:
    Inner() { std::cout << "Inner::Inner()" << std::endl; }
    ~Inner() { std::cout << "Inner::~Inner()" << std::endl; }
};
class Top
{
public:
    Top() { std::cout << "Top::Top()" << std::endl; }
    Top(const Top& other) { std::cout << "Top::Top(const Top&)" << std::endl; }
    ~Top() { std::cout << "Top::~Top()" << std::endl; }
private:
    Inner m_inner;
};
void fun1(Top t)
{
    std::cout << "fun1()" << std::endl;
}
void fun2(Top& t)
{
    std::cout << "fun2()" << std::endl;
}
int main()
{
    std::cout << "Before creating t1" << std::endl;
    Top t1;
    std::cout << "After creating t1" << std::endl;
    std::cout << "Before calling fun1()" << std::endl;
    fun1(t1);
    std::cout << "After calling fun1()" << std::endl;
    std::cout << "Before calling fun2()" << std::endl;
    fun2(t1);
    std::cout << "After calling fun2()" << std::endl;
    return 0;
}



```


 
 
#include <iostream>
class Base
{
public:
    Base() { std::cout << "Base::Base()" << std::endl; }
    ~Base() { std::cout << "Base::~Base()" << std::endl; }
};
class Inner : public Base
{
public:
    Inner() { std::cout << "Inner::Inner()" << std::endl; }
    ~Inner() { std::cout << "Inner::~Inner()" << std::endl; }
};
class Top
{
public:
    Top() { std::cout << "Top::Top()" << std::endl; }
    Top(const Top& other) { std::cout << "Top::Top(const Top&)" << std::endl; }
    ~Top() { std::cout << "Top::~Top()" << std::endl; }
private:
    Inner m_inner;
};
void fun1(Top t)
{
    std::cout << "fun1()" << std::endl;
}
void fun2(Top& t)
{
    std::cout << "fun2()" << std::endl;
}
int main()
{
    std::cout << "Before creating t1" << std::endl;
    Top t1;
    std::cout << "After creating t1" << std::endl;
    std::cout << "Before calling fun1()" << std::endl;
    fun1(t1);
    std::cout << "After calling fun1()" << std::endl;
    std::cout << "Before calling fun2()" << std::endl;
    fun2(t1);
    std::cout << "After calling fun2()" << std::endl;
    return 0;
}
 

首先,Base、Inner、Top 三个类之间的关系是这样的:Top 是一个类,它包含一个 Inner 类的成员变量,Inner 是一个类,它包含一个 Base 类的成员变量。所以可以说 Inner 是 Top 的内部类,Base 是 Inner 的内部类。

为了给这些类添加构造函数和析构函数,并在函数中加入输出语句,我们可以这样做:

class Base {
 public:
  Base() {
    std::cout << "Base 构造函数" << std::endl;
  }
  ~Base() {
    std::cout << "Base 析构函数" << std::endl;
  }
};

class Inner {
 public:
  Inner() {
    std::cout << "Inner 构造函数" << std::endl;
  }
  ~Inner() {
    std::cout << "Inner 析构函数" << std::endl;
  }
  Base b;
};

class Top {
 public:
  Top() {
    std::cout << "Top 构造函数" << std::endl;
  }
  ~Top() {
    std::cout << "Top 析构函数" << std::endl;
  }
  Inner i;
};

现在我们可以在 main 函数中使用这些类来创建和删除对象,并在函数的各个语句执行前或后加入相应的输出信息,以方便观察构造函数和析构函数的执行情况。

int main() {
  std::cout << "在创建 Top 对象之前" << std::endl;
  Top t;
  std::cout << "在创建 Top 对象之后" << std::endl;
  return 0;
}