【问题标题】:Passing variable (from command line) into Class Constructor将变量(从命令行)传递给类构造函数
【发布时间】:2015-12-10 17:53:51
【问题描述】:

我在传递我使用命令行从用户那里获取的变量(array_size)时遇到问题。我需要将此变量传递给 HashMap 构造函数。在构造函数中,如果我将“array_size”更改为 f.e 1000,它可以工作,但我需要它是“变量”:) 这是我的代码,我非常感谢任何帮助。 干杯。

#include<iostream>
#include<cstdlib>

using namespace std;
int counter = 1;

class HashEntry
{
    public:
        string key, value;
        HashEntry(string key, string value)
        {
            this->key = key;
            this->value = value;
        }
};

class HashMap
{
    private:
        HashEntry **table;

    public:
        HashMap()
        {
            table = new HashEntry*[array_size];
            for (int i = 0; i < array_size; i++)
            table[i] = NULL;
        }

        void put(string key, string value, int option, int array_size)
        {
            int _key = atoi(key.c_str());
            int hash = _key;
            if(option == 1)
            {
                while (table[hash] != NULL && table[hash]->key != key)
                {
                    counter++;
                    hash = (hash + 10);
                        }
                hash = hash  % array_size;
            }
            else if(option == 2)
            {
                while (table[hash] != NULL && table[hash]->key != key)
                {
                    counter++;
                    hash = (hash + 10 + counter*counter) % array_size;
                        }
            }
            else if(option == 3)
            {
                while (table[hash] != NULL && table[hash]->key != key)
                {
                    counter++;
                    hash = (hash + counter*(_key%(array_size-2)+1));
                    if(hash >= array_size)
                    {
                        hash = 0;
                    }
                }
                hash = hash % array_size;
            }

            if(table[hash] == NULL)
            {
                table[hash] = new HashEntry(key, value);

            }           
            else
                    {
                if (table[hash] != NULL && table[hash]->key == key)
                {
                    table[hash]->value;
                }               
                else
                {                       
                    table[hash] = new HashEntry(key, value);
                }
            }   
        }
};

int main(int argc, char* argv[])
{
    HashMap map;
    string key, value;
    int array_size;

    array_size = atoi(argv[2]);
    int option = atoi(argv[1]);
    int records;
    cin>>records;

    for(int x = 0; x<records; x++)
    {
        cin >> key;
        cin >> value;
        map.put(key, value, option, array_size);
    }
    cout << counter << endl;
    return 0;
}

【问题讨论】:

  • 要从命令行获取整数值,接受它作为main() 中的字符串数组项或WinMain() 中的字符串,具体取决于您的平台,转换argv[1] 或使用strtol() 的另一个参数或模拟一个整数值,然后将其传递给构造函数。你应该在你的 C 教科书中得到确切的细节。这一切都与对象的构造毫无共同之处,后者主要是另一个话题。

标签: c++ variables constructor parameter-passing


【解决方案1】:

您的 array_size 变量在 main 函数的范围内。如果您希望此代码正常工作,您可以通过将其放在主函数之外(即文件顶部)来使 array_size 具有全局范围。但是你真正应该做的是在 HashMap 类的构造函数中传递 array_size。

#include<iostream>
#include<cstdlib>

using namespace std;
int counter = 1;

class HashEntry
{
    public:
        string key, value;
        HashEntry(string key, string value)
        {
            this->key = key;
            this->value = value;
        }
};

class HashMap
{
    private:
        HashEntry **table;
        int array_size;

    public:
        HashMap(int size) :
            array_size(size)
        {
            table = new HashEntry*[array_size];
            for (int i = 0; i < array_size; i++)
            table[i] = NULL;
        }

        void put(string key, string value, int option, int array_size)
        {
            int _key = atoi(key.c_str());
            int hash = _key;
            if(option == 1)
            {
                while (table[hash] != NULL && table[hash]->key != key)
                {
                    counter++;
                    hash = (hash + 10);
                        }
                hash = hash  % array_size;
            }
            else if(option == 2)
            {
                while (table[hash] != NULL && table[hash]->key != key)
                {
                    counter++;
                    hash = (hash + 10 + counter*counter) % array_size;
                        }
            }
            else if(option == 3)
            {
                while (table[hash] != NULL && table[hash]->key != key)
                {
                    counter++;
                    hash = (hash + counter*(_key%(array_size-2)+1));
                    if(hash >= array_size)
                    {
                        hash = 0;
                    }
                }
                hash = hash % array_size;
            }

            if(table[hash] == NULL)
            {
                table[hash] = new HashEntry(key, value);

            }           
            else
                    {
                if (table[hash] != NULL && table[hash]->key == key)
                {
                    table[hash]->value;
                }               
                else
                {                       
                    table[hash] = new HashEntry(key, value);
                }
            }   
        }
};

int main(int argc, char* argv[])
{
    string key, value;
    int array_size;

    array_size = atoi(argv[2]);
    int option = atoi(argv[1]);
    int records;
    cin>>records;

    HashMap map(array_size);

    for(int x = 0; x<records; x++)
    {
        cin >> key;
        cin >> value;
        map.put(key, value, option, array_size);
    }
    cout << counter << endl;
    return 0;
}

【讨论】:

  • 感谢大家!您的所有反馈都非常有帮助。
【解决方案2】:

叹息。没有人再学习初始化了吗?在知道HashMap 对象应该有多大之前,不要创建它,并为HashMap 提供一个构造函数,该构造函数接受一个提供所需大小的参数。

【讨论】:

    【解决方案3】:

    array_size 参数添加到HashMap 构造函数,并在知道所需数组的大小后实例化map 对象。

    #include<iostream>
    #include<cstdlib>
    
    using namespace std;
    int counter = 1;
    
    class HashEntry {
    public:
        string key, value;
        HashEntry (string key, string value)
        {
            this->key = key;
            this->value = value;
        }
    };
    
    class HashMap {
    private:
        HashEntry **table;
    
    public:
        HashMap (int array_size)    // Add array_size parameter to constructor
        {
            table = new HashEntry*[array_size];
            for (int i = 0; i < array_size; i++)
                table[i] = NULL;
        }
    
        void put (string key, string value, int option, int array_size)
        {
            int _key = atoi (key.c_str ());
            int hash = _key;
            if (option == 1) {
                while (table[hash] != NULL && table[hash]->key != key) {
                    counter++;
                    hash = (hash + 10);
                }
                hash = hash  % array_size;
            }
            else if (option == 2) {
                while (table[hash] != NULL && table[hash]->key != key) {
                    counter++;
                    hash = (hash + 10 + counter*counter) % array_size;
                }
            }
            else if (option == 3) {
                while (table[hash] != NULL && table[hash]->key != key) {
                    counter++;
                    hash = (hash + counter*(_key % (array_size - 2) + 1));
                    if (hash >= array_size) {
                        hash = 0;
                    }
                }
                hash = hash % array_size;
            }
    
            if (table[hash] == NULL) {
                table[hash] = new HashEntry (key, value);
    
            }
            else {
                if (table[hash] != NULL && table[hash]->key == key) {
                    table[hash]->value;
                }
                else {
                    table[hash] = new HashEntry (key, value);
                }
            }
        }
    };
    
    int main (int argc, char* argv[])
    {
        string key, value;
        int array_size;
    
        array_size = atoi (argv[2]);
        int option = atoi (argv[1]);
        int records;
        cin >> records;
    
        HashMap map (array_size);   // Declare map using new constructor
    
        for (int x = 0; x<records; x++) {
            cin >> key;
            cin >> value;
            map.put (key, value, option, array_size);
        }
        cout << counter << endl;
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      在函数中定义的变量,包括main,仅在该函数中可见。

      您需要将大小从main 传递给构造函数

      HashMap(int array_size)
      {
          table = new HashEntry*[array_size];
          for (int i = 0; i < array_size; i++)
          table[i] = NULL;
      }
      

      然后下来main

      array_size = atoi(argv[2]);
      HashMap map(array_size); // now create the hashmap
      

      但是...

      永远不要使用用户输入而不确保它是好的。如果用户提供“fubar”而不是数字怎么办?如果用户指定 -10 怎么办?还是 14.998? atoi 不擅长处理这个。请改用strtoulstd::stoul。两者都只接受正数,并且很容易测试超出范围的值和无效的输入字符。

      HashMap 中存储array_size 作为成员变量也是一个好主意。一个类应该包含并保护它所依赖的所有信息。

      HashMap(unsigned int size): array_size(size)
      {
          table = new HashEntry*[array_size];
          for (int i = 0; i < array_size; i++)
          table[i] = NULL;
      }
      

      和一个新的私有成员变量

      unsigned int array_size;
      

      注意它是unsigned。你不能有一个负大小的数组,那么为什么还要允许这种可能性呢?如果提供了负值,编译器会在启用足够警告的情况下捕获错误。

      并强烈考虑将HashEntry ** 替换为std::vector。使用当前指针方法,您可以获得很多当前未执行的内存管理。你的程序像筛子一样泄漏内存。该向量还可以使您免于违反the Rule of Three

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-16
        • 2016-05-23
        • 1970-01-01
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-12
        相关资源
        最近更新 更多