【问题标题】:How to return a struct from a function in C++?如何从 C++ 中的函数返回结构?
【发布时间】:2013-10-12 20:33:50
【问题描述】:

我在几个不同的论坛上尝试过,似乎无法得到一个直接的答案,我怎样才能让这个函数返回结构?如果我尝试'return newStudent;'我收到错误消息“不存在从 studentType 到 studentType 的合适的用户定义转换。”

// Input function
studentType newStudent()
{   
    struct studentType
    {
        string studentID;
        string firstName;
        string lastName;
        string subjectName;
        string courseGrade;

        int arrayMarks[4];

        double avgMarks;

    } newStudent;

    cout << "\nPlease enter student information:\n";

    cout << "\nFirst Name: ";
    cin >> newStudent.firstName;

    cout << "\nLast Name: ";
    cin >> newStudent.lastName;

    cout << "\nStudent ID: ";
    cin >> newStudent.studentID;

    cout << "\nSubject Name: ";
    cin >> newStudent.subjectName;

    for (int i = 0; i < NO_OF_TEST; i++)
    {   cout << "\nTest " << i+1 << " mark: ";
        cin >> newStudent.arrayMarks[i];
    }

    newStudent.avgMarks = calculate_avg(newStudent.arrayMarks,NO_OF_TEST );
    newStudent.courseGrade = calculate_grade (newStudent.avgMarks);

}

【问题讨论】:

  • 您似乎声明了两个版本的studentType 定义:一个在函数外部,一个在函数内部。您应该只有一个定义,即函数之外的一个。
  • 另外,您可以在堆上分配它并返回一个studentType类型的指针。

标签: c++ function struct return structure


【解决方案1】:

这是您的代码的编辑版本,它基于 ISO C++ 并且与 G++ 配合良好:

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

#define NO_OF_TEST 1

struct studentType {
    string studentID;
    string firstName;
    string lastName;
    string subjectName;
    string courseGrade;
    int arrayMarks[4];
    double avgMarks;
};

studentType input() {
    studentType newStudent;
    cout << "\nPlease enter student information:\n";

    cout << "\nFirst Name: ";
    cin >> newStudent.firstName;

    cout << "\nLast Name: ";
    cin >> newStudent.lastName;

    cout << "\nStudent ID: ";
    cin >> newStudent.studentID;

    cout << "\nSubject Name: ";
    cin >> newStudent.subjectName;

    for (int i = 0; i < NO_OF_TEST; i++) {
        cout << "\nTest " << i+1 << " mark: ";
        cin >> newStudent.arrayMarks[i];
    }

    return newStudent;
}

int main() {
    studentType s;
    s = input();

    cout <<"\n========"<< endl << "Collected the details of "
        << s.firstName << endl;

    return 0;
}

【讨论】:

  • 使用指针来防止复制构造函数不是更高效吗?
  • @JavierCabero 我认为会自动进行复制省略...所以根本没有复制!但如果你真的想管理它,你可以在 struct 对象上实现一些左值移动。
  • 返回一个已经分配到栈上的变量是不是很糟糕?
  • @LittleHelper:如果您通过引用返回,那只会是个问题。
【解决方案2】:

您的范围有问题。在函数之前定义结构体,而不是在函数内部。

【讨论】:

    【解决方案3】:
    studentType newStudent() // studentType doesn't exist here
    {   
        struct studentType // it only exists within the function
        {
            string studentID;
            string firstName;
            string lastName;
            string subjectName;
            string courseGrade;
    
            int arrayMarks[4];
    
            double avgMarks;
    
        } newStudent;
    ...
    

    将其移出函数:

    struct studentType
    {
        string studentID;
        string firstName;
        string lastName;
        string subjectName;
        string courseGrade;
    
        int arrayMarks[4];
    
        double avgMarks;
    
    };
    
    studentType newStudent()
    {
        studentType newStudent
        ...
        return newStudent;
    }
    

    【讨论】:

    • 由于没有使用new操作符创建结构实例,调用newStudent()后会自动删除
    • @Ramesh-X 不,因为new 创建了一个指针,指向在堆上创建的实例。如果您直接返回结构,它只是“复制”(足够智能的编译器可能只使用调用者为返回的结构提供的位置)结构的位到函数调用结果分配给的左值中呼叫者,召集者。当你返回一个“指针”(指针可能是一个引用,实际上并不需要使用指针来实现)到本地结构时,就会出现返回本地结构的问题。
    【解决方案4】:

    您现在 (C++14) 可以返回一个本地定义的(即在函数内部定义的),如下所示:

    auto f()
    {
        struct S
        {
          int a;
          double b;
        } s;
        s.a = 42;
        s.b = 42.0;
        return s;
    }
    
    auto x = f();
    a = x.a;
    b = x.b;
    

    【讨论】:

      【解决方案5】:

      正如其他人指出的那样,在函数之外定义 studentType 。还有一件事,即使您这样做,也不要在函数内创建本地 studentType 实例。该实例位于函数堆栈上,当您尝试返回它时将不可用。但是,您可以做的一件事是动态创建 studentType 并在函数外部返回指向它的指针。

      【讨论】:

      • 如果他创建一个自动的studentType并通过复制返回它,将调用复制构造函数(如果你不创建一个默认创建一个),所以他不会有任何问题.在函数内部声明结构是他的主要问题——目前不需要动态声明。
      • @ZacHowland AIUI,从函数返回内容的默认方法是 move,而不是复制。毕竟,被调用者不再需要它了。
      • @cuddlebugCuller 发表评论时,情况并非如此 :) 自 2013 年以来,已添加并更新了几次移动语义。
      猜你喜欢
      • 1970-01-01
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多