Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to make member function NOT callable from constructor?

Tags:

I have member function (method) which uses

std::enable_shared_from_this::weak_from_this() 

In short: weak_from_this returns weak_ptr to this. One caveat is it can't be used from constructor. If somebody would use my function from constructor of inherited class, weak_from_this inside it would return expired weak_ptr. I guard against that with assertion checking that it's not expired, but it's a run-time check.

Is there a way to check against it at compile time?

like image 266
Korri Avatar asked Apr 08 '19 14:04

Korri


People also ask

What is a difference between defining a non special member function and a constructor?

A constructor is a member function of a class that is used to create objects of that class. It has the same name as the class itself, has no return type, and is invoked using the new operator. An ordinary member function has its own name, a return type (which may be void), and is invoked using the dot operator.

Which member functions are created automatically by the compiler if they are not included in the class definition?

In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it does not declare its own. These functions are known as the special member functions, and they are what make simple user-defined types in C++ behave like structures do in C.

Can a constructor call member functions?

The problem with calling virtual member functions from a constructor is that a subclass can override the function. This will cause the constructor to call the overridden implementation in the subclass, before the constructor for the subclass part of the object has been called.

Why constructor is a special member function?

Answer: A constructor can be defined as a special member function which is used to initialize the objects of the class with initial values. It is special member function as its name is the same as the class name. It enables an object to initialize itself during its creation.


2 Answers

I am afraid the answer is "no, it's not possible to protect against this at compile-time." It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for weak_from_this and shared_from_this in the standard library itself.

like image 75
Angew is no longer proud of SO Avatar answered Oct 13 '22 04:10

Angew is no longer proud of SO


No there is no way. Consider:

void call_me(struct widget*);

struct widget : std::enable_shared_from_this<widget> {
    widget() {
        call_me(this);
    }

    void display() {
        shared_from_this();
    }
};

// later:

void call_me(widget* w) {
    w->display(); // crash
}

The thing is there is a reason you want to check for not calling shared_from_this in the constructor. Think about that reason. It's not that shared_from_this cannot be called, it's because it's return value has no way of being assigned yet. It is also not because it will never be assigned. It's because it will be assigned later in the execution of the code. Order of operation is a runtime property of your program. You cannot assert at compile time for order of operation, which is done at runtime.

like image 42
Guillaume Racicot Avatar answered Oct 13 '22 03:10

Guillaume Racicot