使用构造函数参数实例化 class 对象和不带参数 C++ 的 * 运算符之间的区别

Difference between instantiating a class object with Constructor parameter and * operator without parameters C++

我在学习 C++ 中的 OOPS 概念时遇到了本教程 link。 http://www.tutorialspoint.com/cplusplus/cpp_polymorphism.htm

在基础 class Shape 中,它有一个带有两个参数的构造函数来设置其受保护的变量,在 main() 中我认为唯一的方法是为 [=27 创建一个对象=] Shape 是通过做类似 Shape shape(2,4) 的事情来匹配 Shape class.

中的构造函数

有人能说说不带任何参数的实例化 Shape *shape 是如何工作的吗?通过 Shape shape(2,4)Shape *shape 创建对象有什么区别。

#include <iostream>

using namespace std;

class Shape{
protected:
    int w,h;

public:

    Shape(int a, int b){
        w=a;
        h=b;
    }
    int area(){
        cout << "Shape class area" << endl;
        return 0;
    }
};

class Rect:public Shape{

public:

    Rect(int a, int b):Shape(a,b) {}
    int area(){
        cout <<"Rect class area " << endl;
        return w*h;
    }
};

class Tri:public Shape{

public:

    Tri(int a, int b):Shape(a,b) {}
    int area(){
        cout << "Tri class area" << endl;
        return (w*h)/2;
    }
};

int main(){

    Shape *shape;
    Rect r(4,5);
    Tri t(4,5);
    shape=&r;
    shape->area();
    shape=&t;
    shape->area();
    return 0;
}
Shape *shape;

这不会创建 Shape 对象。它创建一个未初始化的 Shape 指针,可用于存储 Shape 对象(或从 Shape 派生的 class 的对象)的地址。您可以在链接到的页面中看到它的使用:

// store the address of Rectangle
shape = &rec;
// call rectangle area.
shape->area();

声明

Shape *shape;

不会创建 class 形状的任何实例。 它声明一个变量,该变量是 Shape * 类型的指针,并且未初始化,即它具有不确定的值,前提是该声明声明了一个局部变量。

至于构造函数那么 class 的唯一构造函数有两个参数也是 class 的默认构造函数,因为每个参数都有一个默认参数。

Shape( int a=0, int b=0)
           ^^^      ^^^  
{
   //...
}

因此你可以这样写,例如

Shape sh;

创建对象的数据成员将由这些默认参数初始化。 这个声明等同于

Shape sh( 0, 0 );

声明 Shape* 不是运算符,它是不同的类型。类型是指向形状的指针。这在很多方面都不同于直接声明形状:

  • 不是形状,而是指向形状的变量
  • 当使用继承时,我们可以使用指向基class(Shape*)的指针指向一个子class(Rectangle).
  • 请注意,我没有在 Rectangle 之后放置 *。那是因为一个指针指向 class 的一个实例,而不是另一个指针,除非你有指向指针的指针。
  • 声明 Shape* 时,不会调用构造函数,因为您的指针将使用 new 运算符指向现有实例或新实例,或者不指向任何实例。
  • 不指向任何内容的指针通常称为空指针。
  • 你应该在多态之前阅读指针和引用。

不带参数声明的指针具有未定义的值。如果你想要一个空指针,你应该这样声明:

Shape* ptrToShape = nullptr;