c/c + + inheritance and polymorphic container and inheritance 1

Question: Class B inherits class A, class A has virtual function fun, class B covers virtual function fun, and has a STD:: vector < a >. Add object a and object B of a to this container, and then take them out of vector. What happens if you use object a.fun() and object b.fun()?

Find the call of object b.fun(), which actually calls the fun() method of parent class A. That is, the subclass part is cut off.

How to solve this problem? Use STD:: vector < A * > or STD:: vector < STD:: shared_ptr < a > > but smart pointer is recommended.

Quote3.h

#ifndef __QUOTE3_H__
#define __QUOTE3_H__

#include <iostream>
#include <memory>

class Quote{
 public:
  Quote() = default;
  Quote(const std::string& book, double pri)
    :bookNo(book), price(pri){}
  std::string isbn() const{return bookNo;}
  virtual double net_price(std::size_t n)const{
    return n * price;
  }
  virtual void debug()const{
    std::cout << bookNo << " " << price << std::endl;
  }
  virtual ~Quote() = default;
 private:
  std::string bookNo;
 protected:
  double price = 0.0;
};

class Disc_quote : public Quote{
 public:
  Disc_quote() = default;
  Disc_quote(const std::string& book, double price,
         std::size_t qyn, double disc):Quote(book, price),
    quantity(qyn), discount(disc){}
  
  double net_price(std::size_t) const override = 0;
 protected:
  std::size_t quantity = 0;//Quantity for discount
  double discount = 0.0;   //Discount rate
};

class Bulk_quote : public Disc_quote{
 public:
  
  Bulk_quote() = default;
  
  Bulk_quote(const std::string& book, double price,
  std::size_t qyn, double disc)
  :Disc_quote(book, price, qyn, disc){}
  
  double net_price(std::size_t) const override;
};

class Min_quote : public Disc_quote{
 public:

  Min_quote() = default;
  Min_quote(const std::string& book, double price,
       std::size_t qyn, double disc)
   :Disc_quote(book, price, qyn, disc){}
  
  double net_price(std::size_t) const override;
};

#endif

Quote3.cpp

#include "Quote3.h"

double Bulk_quote::net_price(std::size_t cnt) const{
  if(cnt >= quantity){
    return cnt * (1 - discount) * price;
  }
  else{
    return cnt * price;
  }
}


double Min_quote::net_price(std::size_t cnt) const{
  if(cnt < quantity){
    return cnt * (1 - discount) * price;
  }
  else{
    return cnt * price;
  }
}

main.cpp

#include "Quote3.h"
#include <vector>

double print_total(std::ostream& os,
           const Quote& item, size_t n){
  double ret = item.net_price(n);
  os << "ISBN: " << item.isbn()
     << " # sold: " << n << " total due: " << ret << std::endl;
  return ret;

}

int main(){

  std::vector<Quote> qv;
  for(unsigned i = 0; i != 10; ++i){
    qv.push_back(Bulk_quote("01", 100, 10, 0.1));
  }
  double total = 0;
  for(const auto s : qv){
    total += s.net_price(20);
  }
  std::cout << total << std::endl;

  std::cout << "-------------------------" << std::endl;

  std::vector<std::shared_ptr<Quote>> sv;
  for(unsigned i = 0; i != 10; ++i){
    sv.push_back(std::make_shared<Bulk_quote>("01", 100, 10, 0.1));
  }
  double total1 = 0;
  for(const auto s : sv){
    total1 += s->net_price(20);
  }
  std::cout << total1 << std::endl;
  
}

Execution result:

20000
-------------------------
18000

The execution result of STD:: vecto < quote > is 20000; the execution result of STD:: vector < STD:: shared_ptr < quote > > is 18000. So putting smart pointer in the container can solve the above problems.

QQ group of mutual learning in c/c + +: 877684253

My wechat: xiaoshitou5854

Keywords: C++

Added by rage2021 on Sun, 01 Dec 2019 10:45:07 +0200