最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++11 - Implicit type of destructor in c++ - Stack Overflow

programmeradmin1浏览0评论

I know that a destructor in C++ does not return a value and its type cannot be explicitly specified. However, I am wondering whether it can be considered an implicitly void function and whether such a classification is correct according to the C++ standard.

I created a program where type of X destructor is void.

#include <iostream>
#include <cxxabi.h>

using namespace std;

class X
{
};

int main()
{
    X *x = new X();
    char *fullname;

    using destructor_type = decltype(x->~X());
    const type_info  &destructor_t = typeid(destructor_type);

    fullname = abi::__cxa_demangle(destructor_t.name(), NULL, NULL, NULL);
    cout << "[DESTRUCTOR] => " << destructor_t.name() << " => " << fullname << '\n';
    free(fullname);
}

Can you explain to me how it is with destructor?

I know that a destructor in C++ does not return a value and its type cannot be explicitly specified. However, I am wondering whether it can be considered an implicitly void function and whether such a classification is correct according to the C++ standard.

I created a program where type of X destructor is void.

#include <iostream>
#include <cxxabi.h>

using namespace std;

class X
{
};

int main()
{
    X *x = new X();
    char *fullname;

    using destructor_type = decltype(x->~X());
    const type_info  &destructor_t = typeid(destructor_type);

    fullname = abi::__cxa_demangle(destructor_t.name(), NULL, NULL, NULL);
    cout << "[DESTRUCTOR] => " << destructor_t.name() << " => " << fullname << '\n';
    free(fullname);
}

Can you explain to me how it is with destructor?

Share Improve this question asked Feb 6 at 20:10 patb0patb0 431 silver badge2 bronze badges New contributor patb0 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 5
  • 2 A destructor is not an implicitly void function. It is a special member function. A destructor is called when the lifetime of an object ends. – Eljay Commented Feb 6 at 21:01
  • 1 No, a destructor doesn't have a return type. Most likely you get voind because of [this(timsong-cpp.github.io/cppwp/expr.ref#4), but it is not a void function. It is a special member function and those have their own semantics. You can't take the address of constructors or destructors which also helps to show that they aren't normal functions. – NathanOliver Commented Feb 6 at 21:14
  • There are no "void" functions. void is not a function type, it's a data type. For example the type of void foo(int a) is not "void", it's void(int) aka "function taking an int parameter and returning void". E.g. void bar() 's type is not "void" either, it's type is void() aka "function taking no parameter and returning void". – bolov Commented Feb 6 at 21:45
  • From my experience I know that some students and beginners because they first learn that the type of int foo = 24 is int then they make the pattern that the type of a symbol (id) is just the type that appears before that id. This leads them to say/think that the type of int foo(int a, bool b) is "int" , but that's incorrect. As per my previous comment it's "function taking an int and a bool parameters and returning int". – bolov Commented Feb 6 at 21:49
  • 2 The special case you encountered is this: [expr.call]/4 If the postfix-expression names a destructor or pseudo-destructor ([expr.prim.id.dtor]), the type of the function call expression is void – Igor Tandetnik Commented Feb 7 at 1:37
Add a comment  | 

1 Answer 1

Reset to default 5

Note that the difference between an ordinary function's type and its return type. Given the declaration

double f(int);

the type of f is double(int) or "function of int returning double". The return type of f is double.

To be technically correct (the best kind of correct):

  • A destructor does not have a type.
  • A destructor does not have a return type.
  • A function call expression whose function part names a destructor (like x->~X()) has type void.

So,

struct X { ~X(); };
X x;

// Both are errors: Naming a destructor can only be done in
// a declaration or definition, or in a call expression with ().
// If they were valid, the destructor has no type anyway.
using T1 = decltype(X::~X);
using T2 = decltype(x.~X);

using T3 = decltype(x.~X());
static_assert(std::is_same_v<T3, void>); // OK

Note that sometimes decltype gives the type from a name's declaration and sometimes it gives a type based on the type and value category of the expression. This is why decltype(a) and decltype((a)) can be different things. But x.~X() is not directly naming the destructor, so it falls into the category of just getting the expression type, not involving the declaration (explicit or implicit) of ~X.

It's true a destructor is in many ways like a function with return type void: You can use the statement return;, you can't use return with any actual value, and you can't get a value from an expression that calls it.

But there's one little difference showing that a destructor doesn't actually have return type void: A function with return type void can return an expression that has type void. A destructor can't return any expression, even if it does have type void.

void f();

void g(bool b) {
    if (b)
        return f();    // OK, returning void expression as void
    else
        return void(); // Strange but valid way of writing "return;"
}

Y::~Y() {
    if (this->b)
        return f();    // Error, can't put anything after "return"
    else
        return void(); // Error
}
发布评论

评论列表(0)

  1. 暂无评论