/*
* Copyright ©2026 Soham Pardeshi. All rights reserved.
* Permission is hereby granted to students registered for University of
* Washington CSE 333 for use solely during Summer Quarter 2026 for
* purposes of the course. No other use, copying, distribution, or
* modification is permitted without prior written consent. Copyrights
* for third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the author.
*/
#include <iostream>
#include <memory>
#include <vector>
#include "Asset.h"
#include "Cash.h"
#include "DividendStock.h"
#include "Stock.h"
using cse333::Asset;
using cse333::Cash;
using cse333::DividendStock;
using cse333::Stock;
using std::cout;
using std::endl;
int main(int argc, char** argv) {
// ---- Dynamic dispatch through a base pointer (slides 18-20) ----------
DividendStock div("VTI", 10, 2000.0, 250.0);
div.PayDividend(30.0);
Stock* s = ÷ // base pointer to a derived object
// GetMarketValue is virtual, so this runs DividendStock's version even
// though `s` is declared as a Stock*.
cout << "Through Stock*: GetMarketValue = " << s->GetMarketValue() << endl;
// GetProfit is inherited from Stock, but its internal call to
// GetMarketValue() still dispatches to the derived version.
cout << "Through Stock*: GetProfit = " << s->GetProfit() << endl;
// ---- Object slicing: assigning a derived object to a base VALUE ------
// (slide 29). A plain Stock has no room for the dividends_, so it is
// dropped.
Stock sliced = div; // SLICED: Stock's copy of just the Stock part
cout << "\nSliced to Stock: GetMarketValue = " << sliced.GetMarketValue()
<< " (dividends dropped)" << endl;
// ---- A heterogeneous portfolio needs pointers (slide 30) -------------
// vector<Asset> would be impossible (Asset is abstract) and would slice
// anyway. Store unique_ptr<Asset> so the container owns and frees them
// and no slicing happens.
std::vector<std::unique_ptr<Asset>> portfolio;
portfolio.push_back(std::make_unique<Stock>("AAPL", 5, 500.0, 190.0));
portfolio.push_back(std::make_unique<DividendStock>("MSFT", 4, 1200.0, 400.0));
portfolio.push_back(std::make_unique<Cash>(1000.0));
double total = 0.0;
cout << "\nPortfolio:" << endl;
for (const auto& asset : portfolio) {
// One call site, three different GetMarketValue() bodies chosen at
// run time by the actual object type.
cout << " " << asset->name() << ": " << asset->GetMarketValue() << endl;
total += asset->GetMarketValue();
}
cout << "Total market value = " << total << endl;
return EXIT_SUCCESS;
}