Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我想我';我混淆了名称隐藏和函数重写_C++_Inheritance - Fatal编程技术网

C++ 我想我';我混淆了名称隐藏和函数重写

C++ 我想我';我混淆了名称隐藏和函数重写,c++,inheritance,C++,Inheritance,我很困惑……似乎这两件事做的是同一件事 在第一段代码中,我认为派生类隐藏了基类的函数名 #include <iostream> using namespace std; class Quadrilateral { public: void greeting() { std::cout << "i am a quadrilateral" << std::endl; } }; class Square : public Quadr

我很困惑……似乎这两件事做的是同一件事

在第一段代码中,我认为派生类隐藏了基类的函数名

#include <iostream>

using namespace std;

class Quadrilateral {

public:
   void greeting() {
       std::cout << "i am a quadrilateral" << std::endl;
   }
};

class Square : public Quadrilateral {
 public:
    void greeting() {
        std::cout << "i am a square" << std::endl;
    }
};

class Trapezoid : public Quadrilateral {

public:
    void greeting() {   //hides greeting from quadrilateral function
        std::cout << "Hi I'm a Trapezoid" << std::endl;
    }
};

int main()
{
    Trapezoid tz;
    tz.greeting();  
}
#包括
使用名称空间std;
类四边形{
公众:
无效问候语(){

STD::C++中的CUT< P>,如果你声明或有一个结构或类变量,比如这个例子,编译器就知道它的类型,总是调用正确的函数,不管Virtual/No。 虚拟函数只在处理指针或引用时才起作用

尝试在现有代码之后,在main结束之前添加此代码:

Quadrliateral *q = &t;
q->greeting();

您会发现,所有问候语函数是否都是虚拟函数非常重要。

虚拟函数用于从基类指针调用重写函数。 对于第二个示例,如果在
main()

这就是与第一个示例的区别:可以从基类指针调用派生函数。 如果未重写派生类中的虚拟基函数,则将调用基虚拟函数

用法示例。

想象一下,您想要创建许多具有基类
四边形
(例如五个正方形和三个梯形)的对象:

现在,在代码中的某个时刻,您希望抛出所有这些对象并调用抽象函数(在您的例子中是
greeting()
)。因此,借助虚拟函数,您可以做得非常简单:将所有对象放在指针数组中并调用propper函数。下面是如何:

Quadrilateral *base[8] = {&sq1, &sq2, &sq3, &sq4, &sq5, &tz1, &tz2, &tz3};
for (int i = 0; i < 8; i++) {
    base[i]->greeting();
}
Quadrilateral*base[8]={&sq1,&sq2,&sq3,&sq4,&sq5,&tz1,&tz2,&tz3};
对于(int i=0;i<8;i++){
base[i]->greeting();
}
在输出中,您将收到五次
“我是一个正方形”
,三次
“嗨,我是一个梯形”
。 当您创建所有不同的形状(例如,具有不同的尺寸、属性)并希望抛出所有这些对象并调用(例如,
calc()
函数)对每个形状进行单独计算时,它会非常有用


我希望这对您有所帮助。

首先,请格式化您的代码

第一个示例

class Quadrilateral {
  public:
    void greeting() {
      std::cout << "i am a quadrilateral" << std::endl;
  }
};

class Square : public Quadrilateral {
  void greeting() {
    std::cout << "i am a square" << std::endl;
  }
};

class Trapezoid : public Quadrilateral {
  public:
    void greeting() {   //hides greeting from quadrilateral function
      std::cout << "Hi I'm a Trapezoid" << std::endl;
    }
};

int main() {
  Trapezoid tz;
  tz.greeting();  
}
class Quadrilateral {
  public:
   virtual void greeting() {
     std::cout << "i am a quadrilateral" << std::endl;
   }
};

class Square : public Quadrilateral {
  void greeting() {
    std::cout << "i am a square" << std::endl;
  }
};

class Trapezoid : public Quadrilateral {
 public:
  void greeting() {   //hides greeting from quadrilateral function
    std::cout << "Hi I'm a Trapezoid" << std::endl;
  } 
 };

int main() {
  Trapezoid tz;
  tz.greeting();  
}
class Shape {
  public:
    virtual void greeting() {
      std::cout << "Shape" << std::endl;
  }
};

class Square : public Shape {
  /* override method greeting() of Shape class */
  void greeting() {
    std::cout << "Square" << std::endl;
  }
};

class Triangle : public Shape {
  public:
  /* override method greeting() of Shape class */
    void greeting() {   
      std::cout << "Triangle" << std::endl;
    }
};

int main() {
  Shape* shape = new Triangle();
  shape->greeting(); /* prints "Triangle" */
  shape = new Square();
  shape->greeting(); /* prints "Square" */
}
类四边形{
公众:
无效问候语(){

std::cout第二个不是隐藏它,而是覆盖它。我知道,但不管你是覆盖它还是隐藏它,它似乎都会做同样的事情。那有什么意义呢?@LuchianGrigoreTry在这两种情况下都是这样的:创建派生类的一个实例。使用基类的类型创建指向它的指针。在基类指针上调用函数(它实际上指向派生类的一个实例)。@Navin您不必这样做。这只是为了让编译器在您出错时告诉您。注意:
Square::greeting()
通过在第一组中重写为
private
,真正隐藏
quadraside::greeting()
,(我不完全确定你是故意这么做的).Edit:看看这个,完全交互式的,不用进行代码编辑。好吧。没错,我应该知道这一点。但是,我仍然有点困惑,能够使用派生类型对象,通过有一个指向它的基类型指针,到底有什么好处?比如..我从中得到了什么?我注意到唯一不同的是,如果派生类一个未在基类中定义的函数,如果你创建一个指向派生类对象的base*指针,那么派生类中不在基类中的函数将不再可访问。这给了我什么好处?@RichardPlunkettI猜想有时候你想要一个指向任何四边形的指针,但不管它是正方形还是梯形。
class Quadrilateral {
  public:
    void greeting() {
      std::cout << "i am a quadrilateral" << std::endl;
  }
};

class Square : public Quadrilateral {
  void greeting() {
    std::cout << "i am a square" << std::endl;
  }
};

class Trapezoid : public Quadrilateral {
  public:
    void greeting() {   //hides greeting from quadrilateral function
      std::cout << "Hi I'm a Trapezoid" << std::endl;
    }
};

int main() {
  Trapezoid tz;
  tz.greeting();  
}
class Quadrilateral {
  public:
   virtual void greeting() {
     std::cout << "i am a quadrilateral" << std::endl;
   }
};

class Square : public Quadrilateral {
  void greeting() {
    std::cout << "i am a square" << std::endl;
  }
};

class Trapezoid : public Quadrilateral {
 public:
  void greeting() {   //hides greeting from quadrilateral function
    std::cout << "Hi I'm a Trapezoid" << std::endl;
  } 
 };

int main() {
  Trapezoid tz;
  tz.greeting();  
}
class Shape {
  public:
    virtual void greeting() {
      std::cout << "Shape" << std::endl;
  }
};

class Square : public Shape {
  /* override method greeting() of Shape class */
  void greeting() {
    std::cout << "Square" << std::endl;
  }
};

class Triangle : public Shape {
  public:
  /* override method greeting() of Shape class */
    void greeting() {   
      std::cout << "Triangle" << std::endl;
    }
};

int main() {
  Shape* shape = new Triangle();
  shape->greeting(); /* prints "Triangle" */
  shape = new Square();
  shape->greeting(); /* prints "Square" */
}