std::shared_ptr is just a smart pointer, it doesn't care about the members of the object it is holding, only the object itself.
Assigning Aa to Bb will destroy the A object that Bb is holding, and then share ownership of the A object that Aa is holding.
Overloading operator= has nothing to do with whether std::shared_ptr is being used or not. Regardless of how an A object is created, or how its lifetime is being managed, A is responsible for managing its own members, by following the Rule of 3/5/0, which basically states that
if a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.
...
Because the presence of a user-defined destructor, copy-constructor, or copy-assignment operator prevents implicit definition of the move constructor and the move assignment operator, any class for which move semantics are desirable, has to declare all five special member functions
If A's members refer to outside data/resources that A is responsible for deallocating/releasing, then A needs to have proper constructors, destructor, and assignment operators implemented to manage those members properly.
As shown, your A class is likely violating the Rule of 3/5/0, but it is difficult to say for sure as you did not show how the members are being initialized with data.
For example, this would be a violation, since A does not have a destructor to free the new'ed ints that it owns:
class A
{
public:
int* a;
int* b;
int c;
};
class B : public A
{
};
std::shared_ptr<A> Aa = std::make_shared<A>();
a->a = new int(123);
a->b = new int(456);
a->c = 7890;
std::shared_ptr<A> Bb = std::make_shared<B>();
Bb = Aa;
Whereas this would not be a violation, since A does not own the ints that it is pointed at:
class A
{
public:
int* a;
int* b;
int c;
};
class B : public A
{
};
int a = 123;
int b = 456;
std::shared_ptr<A> Aa = std::make_shared<A>();
a->a = &a;
a->b = &b;
a->c = 7890;
std::shared_ptr<A> Bb = std::make_shared<B>();
Bb = Aa;
Assuming A is responsible for owning the allocated memory for the ints , a conforming Rule Of 3/5/0 implementation might look more like this:
class A
{
public:
std::unique_ptr<int> a;
std::unique_ptr<int> b;
int c = 0;
A() = default;
A(const A &src) :
a(std::make_unique<int>(*src.a)),
b(std::make_unique<int>(*src.b)),
c(src.c)
{
}
A(A &&src) :
a(std::move(src.a)),
b(std::move(src.b)),
c(src.c)
{
src.c = 0;
}
virtual ~A() = default;
A& operator=(A rhs)
{
std::swap(a, rhs.a);
std::swap(b, rhs.b);
std::swap(c, rhs.c);
return *this;
}
};
class B : public A
{
};
std::shared_ptr<A> Aa = std::make_shared<A>();
a->a = std::make_unique<int>(123);
a->b = std::make_unique<int>(456);
a->c = 7890;
std::shared_ptr<A> Bb = std::make_shared<B>();
Bb = Aa;