The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science
Lecture/Lab #19
std::optional, containers of polymorphic objects, std::unique_ptr
std::optional<int> read_int(std::istream& in) {
int n;
if ( in >> n ) // check for errors
return n;
return {};
}
int main() {
std::cout << "Enter an integer: ";
if ( auto n = read_int( std::cin ) )
std::cout << "You entered: " << *n << "\n";
else
std::cout << "Unexpected input\n";
}
if ( x )
*x
Returns true if x contains a value
If x contains a value, returns a reference to the contained value, otherwise throws a std::bad_optional_access exception
if ( x.has_value() )
x.value()
If x contains a value, returns a reference to the contained value, otherwise the behavior is undefined.
Given std::optional<T> x ...
x.reset()
Destroys the contained value, if any
x = y;
Assigns x a new value; if x contains a value before the assignment, the contained value is destroyed by calling its destructor
x = obj;
std::vector<car> cars;
cars.push_back( car( "Tesla Model X" ) );
cars.push_back( car( "Honda Accord" ) );
cars.push_back( truck( "Toyota Tacoma", 1620 ) );
for ( auto const& c : cars )
c.print();
Will this work?
car
make_and_model
truck
make_and_model
capacity
car
vector<car>
v[0]
v[1]
v.size()
car
car
car
v[2]
How to make it work
std::vector<std::unique_ptr<car>> cars;
cars.push_back( std::make_unique<car>( "Tesla Model X" ) );
cars.push_back( std::make_unique<car>( "Honda Accord" ) );
cars.push_back( std::make_unique<truck>( "Toyota Tacoma", 1620 ) );
for ( auto const& c : cars )
c->print();
car
"Tesla Model X"
vector<unique_ptr<car>>
v[0]
v[1]
v[2]
car
"Honda Accord"
truck
"Toyota Tacoma"
1620
cars = []
cars.append( Car( "Tesla Model X" ) )
cars.append( Car( "Honda Accord" ) )
cars.append( Truck( "Toyota Tacoma", 1620 ) )
for c in cars:
c.print()
std::vector<std::unique_ptr<car>> cars;
cars.push_back( std::make_unique<car>( "Tesla Model X" ) );
cars.push_back( std::make_unique<car>( "Honda Accord" ) );
cars.push_back( std::make_unique<truck>( "Toyota Tacoma", 1620 ) );
for ( auto const& c : cars )
c->print();
A "smart" pointer with exclusive ownership
std::unique_ptr<T> p;
Creates a unique_ptr instance that doesn't point to/manage any object.
auto p = std::make_unique<T>( ... )
Dynamically allocates a new object of type T by calling a corresponding constructor, takes ownership of the newly created object.
if ( p )
Returns true if p owns an object
*p
If p manages an object, returns a reference to the managed object, otherwise the behavior is undefined.
p->method( ... );
If p manages an object, calls the specified method of the managed object, otherwise the behavior is undefined.
q = std::move( p );
Moves the object ownership from p to q