-2
#include<bits/stdc++.h>
using namespace std;

class student{
    
    public:
    int age;
    string name;
    student(){
        age = 0;
        name = "";
    }
    void setName(string name){
        this->name = name;
    }
    void setAge(int age){
        this->age = age;
    }
    void print(){
        cout<<"Name is: "<<this->name<<"   ";
        cout<<"Age is: "<<this->age<<endl;
    }
};

int main(){
    student s1;
    s1.setAge(20);
    s1.setName("Ajay");
    student s2(s1);
    s1.print();
    cout<<endl;
    s2.print();
    cout<<endl;
    s1.name[0]='B';
    s1.print();
    cout<<endl;
    s2.print();
    cout<<endl;
}
Output:
Name is: Ajay   Age is: 20

Name is: Ajay   Age is: 20

Name is: Bjay   Age is: 20

Name is: Ajay   Age is: 20

As per the shallow copy concept the name of second student should also change( to = "Bjay") since they both share the same memory, but the changes are not being reflected

Why is it so? Don't the both objects share the same memory.

  • 1
    There are no _"shallow copies"_ in your code?? – πάντα ῥεῖ Aug 20 '23 at 07:24
  • You're not making a shallow copy at all, you make a full copy. Also modifying data from "outside" the class is usually a bad practice. You really should change member values only through public functions. One of the main tasks of a class is to guard invariants and you cannot do that if everyone from outside can change things internally in the class. – Pepijn Kramer Aug 20 '23 at 07:24
  • 1
    _"Don't the both objects share the same memory."_ What makes you think they should? – πάντα ῥεῖ Aug 20 '23 at 07:26
  • 3
    To make a "shallow" copy (with all the risks of dangling references) use : `string& name;` for your member variable and add an explicit constructor accepting a `string&` too. Side note : stop using `using namespace std;`. And NEVER use `#include` – Pepijn Kramer Aug 20 '23 at 07:26
  • When we call the default copy constructor, it performs a shallow copy, Isn't it? – Radioactive Aug 20 '23 at 07:27
  • 1
    @Radioactive No it doesn't it will call `std::string`'s copy constructor which will make a deep copy – Pepijn Kramer Aug 20 '23 at 07:27
  • 1
    @Radioactive no, the default copy constructor will invoke a member-wise copy. For `std::string` members it will invoke the `std::string` copy constructor (which will effectively duplicate the string). – wohlstad Aug 20 '23 at 07:34
  • 3
    Side notes: (1) [#include ](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) (2) [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – wohlstad Aug 20 '23 at 07:35
  • Thankyou guys. @PepijnKramer. The 'string& name;' thing worked – Radioactive Aug 20 '23 at 07:49
  • 1
    @Radioactive It will work for now... because you allocate your original string in main, but don't do this with local variables of other functions... you will get crashes. – Pepijn Kramer Aug 20 '23 at 07:52
  • 1
    @Radioactive if you actually need/want to share the object memory use 2 `std::shared_ptr` instances. That's what they're designed for. – πάντα ῥεῖ Aug 20 '23 at 07:58
  • @wohlstad I got the reason behind not using `using namespace std` and `#include ` but I have seen top competitive programmer using these and peronally find it useful just because it saves some efforts and time. – Radioactive Aug 20 '23 at 07:59
  • @πάνταῥεῖ Yeah even that'll help. : ) – Radioactive Aug 20 '23 at 08:02
  • @PepijnKramer Can you please share me some resources where I can read about things you are telling. I am actually not able to understand it completely that why is it happening and what actually happens during run time that it might crash. Thanks – Radioactive Aug 20 '23 at 08:05
  • The important bits are ["scope"](https://en.cppreference.com/w/cpp/language/scope) which determine the life time of objects. And references/pointers, for example you should not return a pointer to a local variable of a function. At the end of the function that local variable no longer exists and if you have a pointer/reference to it and access it your code is no longer correct. Some more explanation [here](https://stackoverflow.com/questions/4643713/returning-a-reference-to-a-local-variable-in-c) – Pepijn Kramer Aug 20 '23 at 08:18
  • 3
    @Radioactive Competitive coding programmers usually don't use C++ correctly. They will use all kind of tricks that they think will speed up their code by a few milliseconds (which is less then the timing accuracy those sites can measure reliably), but in doing so they usually create messy and even incorrect code full of bad practices. – Pepijn Kramer Aug 20 '23 at 08:21
  • If you want more reliable sources have a look at these : A [recent C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) or have a go at https://www.learncpp.com/ (that's pretty decent, and pretty up-to-date). For C++ reference material use : [cppreference](https://en.cppreference.com/w/). And after you learned the C++ basics from those sources, look at the [C++ coreguidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) regularely to keep up-to-date with the latest guidelines. – Pepijn Kramer Aug 20 '23 at 08:22
  • @Radioactive Default copy constructor does not perform a shallow copy. Nor does it perform a deep copy. What it actually does is call the copy constructor for all data members. That could be shallow, or deep, or something else entirely. – john Aug 20 '23 at 08:41
  • @john Alright. I got incorrect information through a youtube video – Radioactive Aug 20 '23 at 09:01
  • @Radioactive That's a problem, any idiot can make a youtube video or a web site. Probably what the video meant what that if your object contains pointers, then those will be shallow copied. That is true. But it's not generally true that a default copy constructor always does a shallow copy. – john Aug 20 '23 at 09:03
  • The default-generated copy constructor will use copy-initialisation of its members. For the member `age`, that is a simple copy of the value of an `int`. For the member `name`, which is a `std::string`, that involves `std::string`'s (noting that `std::string` is actually `std::basic_string`) copy constructor. I'm guessing that, when you say "deep copy" you're *incorrectly* expecting that `std::string`'s copy constructor (which allocates memory, and copies string contents to the new memory) will not be called. – Peter Aug 20 '23 at 14:14

1 Answers1

1

There is no "shallow copy concept" in C++ - there is just copy. Shallow-copy is a mental model when dealing with things other than direct members of objects.

Your student-class only has 2 normal members. When you tell the compiler to copy the class then the default copy-constructor will go through all the members and copy them over.

Shallow-copies would involve having members that do not hold the value directly but indirectly through a pointer or reference. Cause the compiler will still do the exact same thing: Copy over object member-by-member. If the pointer in the first object points towards 0xAB01 then it will simply copy over that values for the pointer in the second class.

Also either make the members of your class private/protected or the set-Methods are useless.

ABaumstumpf
  • 161
  • 1
  • 8