如何正确访问通过从标准输入引用构造函数传递的参数的值?

Posted

技术标签:

【中文标题】如何正确访问通过从标准输入引用构造函数传递的参数的值?【英文标题】:How to properly access the value of a parameter that is passed by reference to a constructor from standard input? 【发布时间】:2019-04-07 09:14:46 【问题描述】:

我正在尝试创建一个最小优先级队列,我遇到的一个问题是我无法弄清楚如何初始化我在命令行中输入的参数的值...我遇到了段错误当我尝试输入值时。

我觉得我遗漏了一些非常明显的东西,但我已经竭尽全力想弄清楚这一点。非常感谢任何帮助,因为我对一般编码很陌生。谢谢。。

    //header file 
   #ifndef __MinPriorityQueue
   #define __MinPriorityQueue

   #include <string>
   #include <list>
   #include <vector>

   using std::vector;
   using std::string;
   using std::list;

class MinPriorityQueue

    public:
        MinPriorityQueue();                       //constructor
        ~MinPriorityQueue();                      //destructor
        void insert(const string&, int key);      //insert string and key
        void decreaseKey(const string id, int newKey);  //decreases key in minqueu
        string extractMin();                      //extracts the min string

    private:
        void buildMinHeap();     //produces a min heap from an unordered array
        void minHeapify(int i);  //maintain the min-heap property
        int parent(int i);       //returns min value 
        int left(int i);         //returns smaller val
        int right(int i);        //returns larger val

        class Element
        
            public:
                Element();
                Element(const string& id, int key);
                ~Element();
            private:
                string* id;
                int key;
        ;
        vector<Element*>minheap;
;

#endif

//.cpp 文件

MinPriorityQueue::Element::Element()

    *id="";
    key=0;

MinPriorityQueue::Element::Element(const string& i, int k )

    *id=i;//segfaults here
    key=k;

//main.cpp

#include "minpriority.h"
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
    char command='w';
    cin>> command;
    MinPriorityQueue minQue;
    while(command!='q')
        if (command== 'a')
        
            string id;
            int key;
            cin>>id>>key;
            minQue.insert(id, key);
        
        else if (command== 'd')
        
            string id;
            int key;
            cin>>id>>key;
            minQue.decreaseKey(id, key);
        
        else if (command== 'x')
        
            cout<<minQue.extractMin()<<endl;
        
        cin>>command;
    
    return 0;

【问题讨论】:

你为什么将id成员设为指针? string* id; 为什么要在此处存储指向字符串的指针?这可能就是你的程序失败的原因。 我老师想让我们那样做,我也觉得很奇怪。 “我的老师希望我们这样做”。我很难相信……他有没有提到任何关于const char * 的事情?从字符串中删除指针,代码就可以正常工作了。 @ConstantinosGlynos 不,她给了我们 .h 文件和函数的名称 【参考方案1】:

您的代码不起作用的原因是,当指针 id 没有分配内存时,您尝试通过取消引用 *id = " "*id = i 为指针 std::string *id 赋值。这意味着它不能被取消引用。

有多种方法可以“修复”您的程序。

选项 1:std::string *id 设为 const 并从 main 中分配 user_id 变量的地址。

class MinPriorityQueue

    private:
        class Element
        
            private:
                const std::string *id;
                int key;

            public:
                Element(const std::string &i, int k)
                
                    id = &i;
                    key = k;
                
                ~Element() = default;
        ;
        std::vector<Element*> minheap;

    public:
        void insert(const std::string &s, int k)
        
            minheap.push_back(new Element(s,k));
        
;

int main()

    MinPriorityQueue minQue;

    std::string user_id = "test";
    minQue.insert(user_id, 2);

选项2:std::string *id分配内存。

class MinPriorityQueue

    private:
        class Element
        
            private:
                std::string *id;
                int key;

            public:
                Element(const std::string &i, int k)
                
                    id = new std::string(i);
                    key = k;
                
                ~Element() = default;
        ;
        std::vector<Element*> minheap;

    public:
        void insert(const std::string &s, int k)
        
            minheap.push_back(new Element(s,k));
        
;

int main()

    MinPriorityQueue minQue;

    minQue.insert("test", 2);

选项3:从函数参数中删除const,以便将其地址分配给非常量成员指针。

class MinPriorityQueue

    private:
        class Element
        
            private:
                std::string *id;
                int key;

            public:
                Element(std::string &i, int k)
                
                    id = &i;
                    key = k;
                
                ~Element() = default;
        ;
        std::vector<Element*> minheap;

    public:
        void insert(std::string &s, int k)
        
            minheap.push_back(new Element(s,k));
        
;

int main()

    MinPriorityQueue minQue;

    std::string user_id = "test";
    minQue.insert(user_id, 2);

选项 4(也是我个人最喜欢的):将 std::string *id; 指针转换为普通字符串 std::string id;

ps。使用指针方法,您的默认构造函数应该分配内存并将字符串初始化为空字符串std::string *id = new std::string("");,或者将其定义为空指针std::string *id = nullptr;

希望这会有所帮助。

【讨论】:

以上是关于如何正确访问通过从标准输入引用构造函数传递的参数的值?的主要内容,如果未能解决你的问题,请参考以下文章

移动选定的构造函数而不是复制。 [参考标准]

通过从另一个方法引用设置 NSString

如何将双精度向量传递给构造函数,然后在子类中访问其数据(在 C++ 中)?

如何通过从 aspx.cs 文件中获取参数来执行数据库 CRUD 操作?

使用从构造函数传递到方法的类中的参数访问rest

c++中如何用函数传递fstream类型