如果我在构造函数中写 return 语句怎么办?

发布于 2024-10-21 14:40:11 字数 610 浏览 8 评论 0原文

如果我在构造函数中写 return 语句怎么办?是否符合标准?

struct A
{ 
     A() { return; } 
};

上面的代码编译良好,在 ideone 上没有任何错误。但以下代码却没有:

struct A
{ 
   A() { return 100; } 
};

它在 ideone 处给出了此错误:

错误:从构造函数返回值

我知道从构造函数返回值根本没有意义,因为它没有明确提及返回类型,而且我们毕竟无法存储返回值。但我很想知道:

  • C++ 标准中的哪条语句允许第一个示例但禁止第二个示例?有没有明确的声明?
  • 第一个示例中的返回类型是 void 吗?
  • 是否有任何隐式返回类型?

What if I write return statement in constructor? Is it standard conformant?

struct A
{ 
     A() { return; } 
};

The above code compiles fine, without any error at ideone. But the following code doesn't:

struct A
{ 
   A() { return 100; } 
};

It gives this error at ideone:

error: returning a value from a constructor

I understand that returning value from constructor doesn't make sense at all, because it doesn't explicitly mention return type, and we cannot store the returned value after all. But I'm curious to know :

  • Which statement from the C++ Standard allows the first example but forbids the second one? Is there any explicit statement?
  • Is the return type in the first example void?
  • Is there any implicit return type at all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

但可醉心 2024-10-28 14:40:11

是的,在构造函数中使用 return 语句是完全标准的。

构造函数是不返回值的函数。不返回值的函数系列包括:void 函数、构造函数和析构函数。 C++标准中的6.6.3/2中有规定。同样的 6.6.3/2 规定,在不返回值的函数中使用带有参数的 return 是非法的。

6.6.3 返回语句

2 没有返回语句
表达式只能用于
不返回值的函数,
也就是说,一个带有 return 的函数
void 类型、构造函数 (12.1) 或
析构函数(12.4)。退货声明
具有非 void 类型的表达式
只能在函数中使用
返回一个值;的价值
表达式返回给调用者
的功能。

此外,12.1/12 规定

12.1 构造函数

12 不得返回类型(甚至无效)
为构造函数指定。一个
a 正文中的 return 语句
构造函数不得指定返回值
值。

请注意,顺便说一句,在 C++ 中,在 void 函数中使用带有参数的 return 是合法的,只要 return 的参数具有 void 类型。 code>

void foo() {
  return (void) 0; // Legal in C++ (but not in C)
}

但这在构造函数中是不允许的,因为构造函数不是 void 函数。

还有一个与构造函数中使用 return 相关的相对模糊的限制:在构造函数的函数 try 块中使用 return 是非法的(与其他函数一起使用)好的)

15.3 处理异常

15 如果退货声明出现在
a 的函数 try 块的处理程序
构造函数,程序格式错误。

Yes, using return statements in constructors is perfectly standard.

Constructors are functions that do not return a value. The family of functions that do not return a value consists of: void functions, constructors and destructors. It is stated in 6.6.3/2 in the C++ standard. The very same 6.6.3/2 states that it is illegal to use return with an argument in a function that does not return a value.

6.6.3 The return statement

2 A return statement without an
expression can be used only in
functions that do not return a value,
that is, a function with the return
type void, a constructor (12.1), or a
destructor (12.4). A return statement
with an expression of non-void type
can be used only in functions
returning a value; the value of the
expression is returned to the caller
of the function.

Additionally, 12.1/12 states that

12.1 Constructors

12 No return type (not even void) shall
be specified for a constructor. A
return statement in the body of a
constructor shall not specify a return
value.

Note, BTW, that in C++ it is legal to use return with an argument in a void function, as long as the argument of return has type void

void foo() {
  return (void) 0; // Legal in C++ (but not in C)
}

This is not allowed in constructors though, since constructors are not void functions.

There's also one relatively obscure restriction relevant to the usage of return with constructors: it is illegal to use return in function-try-block of a constructor (with other functions it is OK)

15.3 Handling an exception

15 If a return statement appears in a
handler of the function-try-block of a
constructor, the program is ill formed.

小猫一只 2024-10-28 14:40:11

也许在构造函数中具有无类型返回的概念是为了控制构造函数的终止。

struct A
{ 
// more definitions     
A() 
{ 
if( !goodToGoOn)  
 return;
// the rest of the stuffs go here
} 
};

Perhaps the notion of having typeless return in constructors is to control the termination of constructor function.

struct A
{ 
// more definitions     
A() 
{ 
if( !goodToGoOn)  
 return;
// the rest of the stuffs go here
} 
};
娇妻 2024-10-28 14:40:11

根据定义,构造函数确实返回一些东西。

对于下面的代码,

#include <string>
#include <iostream>
using namespace std;

class dog{
    private:
        string _name;
        string _breed;
    public:
        //initialise private variables to those passed in
        void init(string name, string breed)
        {
            _name = name;
            _breed = breed;
        }

        void bark(){cout << "BARK! BARK! My name is " << getName() << "\n";}

        string getBreed(){return _breed;}
        string getName(){return _name;}
    };

//can run with
int main(int argc, char** argv){
    //create a dog named Sally
    dog sally;
    //Initialise its variables
    sally.init("sally", "chocolate lab");
    sally.bark();
}

这里我们创建一个 void 类型函数来初始化我们的狗对象,然后在我们的 main 函数中,我们必须在新的狗对象上调用该 init 函数。但是如果使用构造函数,我们的代码看起来就像这样

#include <string>
#include <iostream>
using namespace std;

class dog{
    private:
        string _name;
        string _breed;

    public:
        //Dog constructor to initialize passed in variables
        dog(string name, string breed){
            _name = name;
            _breed = breed;
        }

        void bark(){cout << "BARK! BARK! My name is " << getName() << "\n";}

        string getBreed(){return _breed;}
        string getName(){return _name;}
};

//can run with
int main(int argc, char** argv){
    //create a dog named Sally
    dog sally("sally", "chocolate lab");
    sally.bark();
}

这段代码本质上是同样的事情,但它是为了表明构造函数初始化传入的变量并返回对象本身。

你不能说

dog(string name, string breed)
    {
        _name = name;
        _breed = breed;
        return cout << "BARK! BARK! My name is " << getName() << "\n";
    }

A constructor by definition does return something.

For the code below,

#include <string>
#include <iostream>
using namespace std;

class dog{
    private:
        string _name;
        string _breed;
    public:
        //initialise private variables to those passed in
        void init(string name, string breed)
        {
            _name = name;
            _breed = breed;
        }

        void bark(){cout << "BARK! BARK! My name is " << getName() << "\n";}

        string getBreed(){return _breed;}
        string getName(){return _name;}
    };

//can run with
int main(int argc, char** argv){
    //create a dog named Sally
    dog sally;
    //Initialise its variables
    sally.init("sally", "chocolate lab");
    sally.bark();
}

Here we create a void type function that initializes our dog object, then in our main function we must call that init function on our new dog object.But if use a constructor our code looks instead like

#include <string>
#include <iostream>
using namespace std;

class dog{
    private:
        string _name;
        string _breed;

    public:
        //Dog constructor to initialize passed in variables
        dog(string name, string breed){
            _name = name;
            _breed = breed;
        }

        void bark(){cout << "BARK! BARK! My name is " << getName() << "\n";}

        string getBreed(){return _breed;}
        string getName(){return _name;}
};

//can run with
int main(int argc, char** argv){
    //create a dog named Sally
    dog sally("sally", "chocolate lab");
    sally.bark();
}

This code does essentially the same thing but it is to show that a constructor initializes the passed in variables and returns the object itself.

You cannot say

dog(string name, string breed)
    {
        _name = name;
        _breed = breed;
        return cout << "BARK! BARK! My name is " << getName() << "\n";
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文