0

I am creating a text editor and I want to use the TextContent class object in two other classes: Editor and InputManager. The problem occurs when changing the buffer in InputManager - the buffer in Editor does not change despite passing by reference TextContent to both classes.

I discovered that the cause is the different address of the buffer in these classes, and the change occurs after calling the constructors.

Code:

Editor::Editor(
        sf::RenderWindow &window,
        TextContent &content) : textContent(content)
{
    std::cout << "Buffer in Editor constructor" << std::endl;
    std::cout << &content.buffer << std::endl;
}
InputManager::InputManager(TextContent &content)
    :textContent(content)
{
    std::cout << "Buffer in InputManager constructor" << std::endl;
    std::cout << &textContent.buffer << std::endl;
}
TextContent::TextContent(std::string &filepath)
{
    std::ifstream fileStream;
    fileStream.open(filepath, std::ios::in);
    if(!fileStream)
    {
        std::cout << "No such file" << std::endl;
    }
    else
    {
        std::ostringstream sstr;
        sstr << fileStream.rdbuf();
        buffer += sstr.str();
    }
    fileStream.close();
    std::cout << "Buffer in TextContent constructor" << std::endl;
    std::cout<< &buffer << std::endl;
}
int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "TestEditor");
    std::string path = "./samples/empty.txt";
    TextContent content(path);
    Editor editor(window, content);
    InputManager in_manager(content);

    std::cout << "After init in TextContent:" << std::endl;
    std::cout << &content.buffer << std::endl;
    std::cout << "After init in Editor:" << std::endl;
    std::cout << &(editor.textContent.buffer) << std::endl;
    std::cout << "After init in InputManager:" << std::endl;
    std::cout << &(in_manager.textContent.buffer) << std::endl;

Output:

Buffer in TextContent constructor
0x7ffe334926a0
Buffer in Editor constructor
0x7ffe334926a0
Buffer in InputManager constructor
0x7ffe334926a0
After init in TextContent:
0x7ffe334926a0
After init in Editor:
0x7ffe33492ae0
After init in InputManager:
0x7ffe334926c0

I am beginner in C++ and have no idea why immediately after executing the constructor address of buffer changes.

Could you find the reason please?

MikeDarni
  • 1
  • 1
  • What are the types of the `textContent` member variables for each class? I suspect a copy being created somewhere without you expecting it. If you don't want a new version of an object of one of your types to be created based on an existing one, you should remove any existing copy/move constructors/assignment operators and define move constructor and assignment operator as deleted, which also results in the corresponding members for copy semantics to be deleted. This should result in a compiler error indicating the copy, if my assumption is correct. – fabian Aug 21 '22 at 08:56
  • Why is the parameter type of `TextContent::TextContent` `std::string&` instead of `std::string const&` btw? You've removing the possiblity of calling the constructor with a string literal here for no obvious reason: applying my suggestion you could use `TextContent content("./samples/empty.txt");` without needing to create a local variable to pass to the constructor... – fabian Aug 21 '22 at 09:03
  • @fabian in both cases it is a public field of the TextContent type. I have no copy/move constructors anywhere in the code and therefore the behavior is all the more surprising to me :/ – MikeDarni Aug 21 '22 at 09:04
  • @fabian yes you are right, a small oversight on my part :) – MikeDarni Aug 21 '22 at 09:10
  • Copy&move semantics are implicitly defined in many cases, see https://stackoverflow.com/a/38257488/2991525 and if the type is `TextContent` not `TextContent&` then there's a copy made... – fabian Aug 21 '22 at 09:11
  • @fabian Thank you very much, it works now. How can I reward you here? I don't see upvote or smth – MikeDarni Aug 21 '22 at 09:26

0 Answers0