sharedbug.cc

#include <cstdlib>   // for EXIT_SUCCESS
#include <iostream>  // for std::cout, std::endl
#include <memory>    // for std::shared_ptr

int main(int argc, char **argv) {
  // x contains a pointer to an int and has reference count 1.
  std::shared_ptr<int> x(new int(10));
  // y contains a pointer to the same int and it now has reference
  // count 2 - works fine
  std::shared_ptr<int> y(x);

  int *p = new int;

  // xbug contains a pointer to int *p and has reference count 1.
  std::shared_ptr<int> xbug(p);

  // ybug contains a pointer to the same *p and also has a reference
  // count of 1.  x and y don't know about each other
  std::shared_ptr<int> ybyg(p);

  // on exit, x and y decrement their shared reference count and the
  // shared int they own is correctly deleted once.
  // BUT: xbug and ybug both independently delete their separate
  // reference counts and the p is deleted twice - bug!
  return EXIT_SUCCESS;
}

initial_design

Stock.h

#ifndef STOCK_H_
#define STOCK_H_

#include <string>

using std::string;

// A Stock object represents purchases of shares of a stock.
class Stock {
 public:
  Stock(const string& symbol, double share_price = 0.0);
  virtual ~Stock() = default;

  // Stock's mutator/accessor methods.
  virtual void   Purchase(const int shares, const double share_price);
  virtual string get_symbol() const;
  virtual int    get_shares() const;
  virtual double get_share_price() const;
  virtual void   set_share_price(const double share_price);

  // Stock's "investment" interface.
  virtual double GetCost() const;
  virtual double GetMarketValue() const;
  virtual double GetProfit() const;

  // Print out the Stock information.
  virtual void Print() const;

 private:
  string symbol_;
  int    shares_;
  double cost_;
  double share_price_;
};

#endif  // STOCK_H_

Stock.cc

#include <iostream>
#include <iomanip>

#include "Stock.h"

using std::cout;
using std::endl;
using std::setw;

// Constructs a new Stock with the given symbol and current price per share.
Stock::Stock(const string& symbol, const double share_price) {
  symbol_ = symbol;
  share_price_ = share_price;
  cost_ = 0.0;
  shares_ = 0;
}

// Gets the stock symbol.
string Stock::get_symbol() const {
  return symbol_;
}

// Returns the total number of shares purchased.
int Stock::get_shares() const {
  return shares_;
}

// Returns the price per share of this asset.
double Stock::get_share_price() const {
  return share_price_;
}

// Sets the current share price of this asset.
void Stock::set_share_price(const double share_price) {
  share_price_ = share_price;
}

// Returns this asset's total cost spent on all shares.
double Stock::GetCost() const {
  return cost_;
}

// Returns the market value of this stock, which is the total number
// of shares times the share price.
double Stock::GetMarketValue() const {
  return get_shares() * get_share_price();
}

// Returns the profit earned on this stock.
double Stock::GetProfit() const {
  return GetMarketValue() - GetCost();
}

// Records a purchase of the given number of shares of stock at the
// given price per share.
void Stock::Purchase(const int shares, const double share_price) {
  shares_ += shares;
  cost_ += shares * share_price;
}

// Print out the stock information.
void Stock::Print() const {
  cout << "Stock (" << get_symbol() << "):" << endl;
  cout << "  value: $" << setw(7) << GetMarketValue() << endl;
  cout << "   cost: $" << setw(7) << GetCost() << endl;
  cout << " profit: $" << setw(7) << GetProfit() << endl;
}

DividendStock.h

#ifndef DIVIDENDSTOCK_H_
#define DIVIDENDSTOCK_H_

#include <string>

#include "Stock.h"

using std::string;

// Represents a stock purchase that also pays dividends.
class DividendStock : public Stock {
 public:
  DividendStock(const string& symbol, const double share_price = 0.0);

  // DividendStock's mutator and accessor methods.
  virtual void PayDividend(const double amount_per_share);

  // DividentStock's "investment" interface.
  double GetMarketValue() const override;
  virtual double GetDividends() const;

  // Print out the DividendStock information.
  void Print() const override;

 private:
  double dividends_;
};

#endif  // DIVIDEND_STOCK_

DividendStock.cc

#include <iostream>
#include <iomanip>

#include "DividendStock.h"

using std::cout;
using std::endl;
using std::string;
using std::setw;

// Constructs a new dividend stock with the given symbol and no shares.
DividendStock::DividendStock(const string& symbol, const double share_price)
  : Stock(symbol, share_price) {
  dividends_ = 0.0;
}

// Returns the market value of this stock, which is the total number
// of shares times the share price, plus dividends
double DividendStock::GetMarketValue() const {
  return get_shares() * get_share_price() + dividends_;
}

// Returns the total amount of dividends paid on this stock.
double DividendStock::GetDividends() const {
  return dividends_;
}

// Records a dividend of the given amount per share.
void DividendStock::PayDividend(const double amount_per_share) {
  dividends_ += amount_per_share * get_shares();
}

// Print out the Dividendstock information.
void DividendStock::Print() const {
  cout << "DividendStock (" << get_symbol() << "):" << endl;
  cout << "  value: $" << setw(8) << GetMarketValue() << endl;
  cout << "   cost: $" << setw(8) << GetCost() << endl;
  cout << " profit: $" << setw(8) << GetProfit() << endl;
}

useassets.cc

#include <cstdlib>

#include <iostream>
#include <iomanip>
#include <vector>

#include "Stock.h"
#include "DividendStock.h"

using std::cout;
using std::endl;

int main() {
  // create several investments
  Stock* stock = new Stock("MSFT");
  stock->Purchase(50, 10.00);
  stock->set_share_price(9.50);

  DividendStock* dividend = new DividendStock("INTC");
  dividend->Purchase(100, 20.00);
  dividend->PayDividend(5.00);
  dividend->set_share_price(30);

  // display info about each investment
  stock->Print();
  cout << endl;
  dividend->Print();

  delete stock;
  delete dividend;

  return EXIT_SUCCESS;
}

Makefile

CXX = g++
CFLAGS = -g -Wall -std=c++17
HEADERS = Stock.h DividendStock.h
OBJS = Stock.o DividendStock.o useassets.o

all: useassets

useassets: $(OBJS)
    $(CXX) $(CFLAGS) -o $@ $^

.cc.o: $(HEADERS)
    $(CXX) $(CFLAGS) -c $<

clean: FORCE
    /bin/rm -f *~ *.o useassets

FORCE: