c++ Passing *this as reference during construction of self

11,712

Solution 1

(Note: gInst doesn't actually use the reference until much later.)

Then it's completely safe. (Taking note you say "the reference", not "the value".)

Compilers will just warn about it for the reason you've stated, but there's nothing undefined about it, just "risky". Note that you can often trump compiler warnings (if they bother you) with something like this:

struct foo
{
    foo() : b(self())
    {}

private:
    foo& self() { return *this; }

    bar b;
};

Solution 2

As long as gInst never accesses a data member or member function of gInst or attempts to perform run-time type introspection via RTTI or dynamic_cast, until after the constructor has completed, then it is safe.

Solution 3

The short answer: Maybe, if you're careful.

The long answer: https://isocpp.org/wiki/faq/ctors#using-this-in-ctors

Relating to your specific issue: That's fine, as long as gInst really is a reference.

(a class called System in the namespace System in the namespace Sys? o.O)

Share:
11,712

Related videos on Youtube

Truncheon
Author by

Truncheon

C++ novice

Updated on June 04, 2022

Comments

  • Truncheon
    Truncheon about 2 years

    Is the following safe? I know, strictly speaking, dereferencing a pointer before the thing to which it points has been properly constructed seems dangerous, but I imagine the compiler will just provide a pointer without actually doing any dereferencing. Well, I assume.

    (Note: gInst doesn't actually use the reference until much later.)

    TU 1

    Sys::System::System::System(const sf::VideoMode& rVM, const std::string& rSTR, unsigned long settings) :
        win(rVM, rSTR, settings),
        gInst(*this)
    {
    
    }
    

    Header A

    namespace Sys
    {
        namespace System
        {
            struct System;
        }
    
        namespace UI
        {
            struct GUI
            {
                System::System& topl;
                MenuBar menu;
    
                GUI(System::System&);
    
                private:
    
                GUI();
                GUI(const GUI&);
                GUI& operator=(const GUI&);
            };
        }
    }
    

    Header B

    namespace Sys
    {
        namespace System
        {
            struct System
            {
                sf::RenderWindow win;
                Sys::UI::GUI gInst;
                Sys::Editor::Editor eInst;
    
                System(const sf::VideoMode&, const std::string&, unsigned long);
    
                private:
    
                System();
                System(const System&);
                System& operator=(const System&);
            };
    
            void start();
        }
    }
    
  • jupp0r
    jupp0r about 9 years
    Unfortunately, link is broken.