Skip to content

Instantly share code, notes, and snippets.

@alifarazz
Last active January 19, 2022 17:50
Show Gist options
  • Save alifarazz/cf949bbbf3729d48fa4470d74d0a24a5 to your computer and use it in GitHub Desktop.
Save alifarazz/cf949bbbf3729d48fa4470d74d0a24a5 to your computer and use it in GitHub Desktop.
Exploration of "object slicing" in c++ classes
#include <iostream>
#include <vector>
#include <memory>
using namespace std::literals;
class Base
{
public:
virtual auto who() const -> std::string { return "Base"s; }
int m_base;
};
class Derived1 : public Base
{
public:
auto who() const -> std::string final override { return "Derived1"s; }
int m_derived;
};
class Holder {
public:
// either constructor can be used, it has no impact on whether object slicing occurs or not
Holder(Base& b1, Base& b2) : b1{b1}, b2{b2} {}
Holder(Base& b1, Derived1& b2) : b1{b1}, b2{b2} {}
Base& b1, b2;
std::string show() {
return b1.who() + "\n" + b2.who();
}
static std::string caller(Base& b) {
return b.who();
}
};
void test_vector() { // no slicing
std::unique_ptr<Base> b1 = std::make_unique<Base>();
std::unique_ptr<Base> d1 = std::make_unique<Derived1>();
std::vector<std::unique_ptr<Base>> bv;
bv.push_back(std::move(b1));
bv.push_back(std::move(d1));
for (auto& p: bv)
std::cout << p->who() << std::endl;
}
void test_holder() { // slicing happens
Base b1;
Derived1 d1;
Holder h(b1, d1);
std::cout << h.show() << std::endl; // d1 slices // UB??
std::cout << Holder::caller(d1) << std::endl; // no slicing!
}
int main()
{
test_vector();
std::cout << std::string(80, '-') << std::endl;
test_holder();
}
/* output:
Base
Derived1
--------------------------------------------------------------------------------
Base
Base
Derived1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment