在类中捕获错误/异常

时间:2015-12-17 22:13:26

标签: c++ class exception error-handling exception-handling

我编写了一个类,在您提供种子,序列长度和字符集后返回一个随机字符串,如下所示。

我想知道如何捕获任何错误输入,例如将种子设置为0或负数。

我见过的例子刚刚使用cout发送错误信息然后退出(1);我正在考虑将bool标志作为私有变量,并在检测到无效输入时将其设置为false。然后,在尝试使用此类生成随机字符串之后,您只需通过访问器函数检查该标志。

是否有更好的和/或标准的处理方法,不会像exit(1)那样退出程序?关于班级的任何一般性意见也受到欢迎。谢谢你的帮助。

RandomString.h

// This is the header file randomstring.h. This is the interface for the class RandomString.
// Values of this type are a random string of the specified length from the specified string character set.
// The values that are needed for input are a positive integer seed, an integer desired length, and a string character set.
// Uses the mt19937 random number engine with a uniform_int_distribution.
#ifndef RANDOMSTRING_H
#define RANDOMSTRING_H

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

namespace RandomString
{
    class RandomString
    {
    public:
        RandomString(double newSeed, unsigned int newLength, string newCharacterSet);   // Initializes the RandomString object with the provided arguments.
        RandomString(); // Initializes the seed to 1, the length to 0, and the character set to '0'.
        double getSeed();
        unsigned int getLength();
        string getCharacterSet();
        string getSequence();
        void setSeed(double newSeed);   // Sets the new seed but does not produce a new random sequence.
        void setLength(unsigned int newLength); // This is the length of randomSequence.
        void setCharacterSet(string newCharacterSet);
        void generateNext();    // Generates the next random sequence.

    private:
        double seed;
        unsigned int length;
        string characterSet;
        string randomSequence;
        mt19937 engine;
    };

} // RandomString namespace

#endif

RandomString.cpp

// This is the implementation file randomstring.cpp. This is the implementation for the class RandomString.
// The interface for the class RandomString is in the header file randomstring.h.
#include "stdafx.h"
#include <string>
#include <random>
#include "randomstring.h"

using std::string;
using std::uniform_int_distribution;

namespace RandomString
{
    RandomString::RandomString(double newSeed, unsigned int newLength, string newCharacterSet)
    {
        setSeed(newSeed);
        setLength(newLength);
        setCharacterSet(newCharacterSet);
    }

    RandomString::RandomString()
    {
        seed = 1;
        length = 0;
        characterSet = '0';
    }

    double RandomString::getSeed()
    {
        return seed;
    }

    unsigned int RandomString::getLength()
    {
        return length;
    }

    string RandomString::getCharacterSet()
    {
        return characterSet;
    }

    string RandomString::getSequence()
    {   
        return randomSequence;
    }

    void RandomString::setSeed(double newSeed)
    {
        seed = newSeed; 
        engine.seed(seed);
    }

    void RandomString::setLength(unsigned int newLength)
    {
        length = newLength;
    }

    void RandomString::setCharacterSet(string newCharacterSet)
    {
        characterSet = newCharacterSet;
    }

    void RandomString::generateNext()
    {
        randomSequence.resize(length);
        uniform_int_distribution<> distribution(0,characterSet.length() - 1);

        for (int i = 0; i < length; i++)
        {
            randomSequence[i] = characterSet[distribution(engine)];
        }

    }
} // RandomString namespace

最后,这是我正在使用的测试程序。

// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include "randomstring.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    do
    {
        double seed = 0;
        unsigned int length = 0;

        cout << "Enter seed: ";
        cin >> seed;
        cout << "Enter length of string: ";
        cin >> length;
        cout << endl;

        RandomString::RandomString randomTest(seed,length,"ABCDEFGHJKLMNPQRSTUVWXYZ1234567890"); 
        cout << "class RandomString" << endl;
        cout << "seed: " << randomTest.getSeed() << endl;
        cout << "length: " << randomTest.getLength() << endl;
        randomTest.generateNext();
        cout << "random sequence: " << randomTest.getSequence() << endl;
        randomTest.generateNext();
        cout << "next random sequence: " << randomTest.getSequence() << endl << endl;

    }while(true);

}

2 个答案:

答案 0 :(得分:0)

如何让用户有另一次机会提供良好的输入?

用户在发现输入错误后会做的下一步是什么?很有可能他们会再次尝试输入,所以只需要另外一个。

while(true) 
{
    cout << "Enter seed: ";
    cin >> seed;

    if(seed > 0)
    {
        cout << "ERROR: Seed must be greater than 0." << endl;
        break;
    }
}

要回答有关bool错误标记的问题,我不会这样做。我不需要从坏种子生成的错误数据。没有数据比坏数据更好。我通常会尝试早期失败,经常失败&#34;,这意味着我应该在我意识到存在时立即停止并报告错误。

如果你设置存储错误标记,我会generateNext()setSeed返回false,而不是在有问题时返回任何内容。例外也有效,但速度较慢,有些项目在C ++中不喜欢它们。

如果您打算让其他人使用RandomString,我会将方法签名从double更改为uint(unsigned int)。这将捕获在编译时而不是运行时使用的负数...再次帮助甚至更早失败。听起来这可能不适合您的课堂场景,但在现实世界中这是一个很好的原则。

答案 1 :(得分:0)

抛出异常

void RandomString::setSeed(double newSeed)
{
    if (newSeed <= 0) {
        throw std::runtime_error("seed should be positive");
    }
    seed = newSeed; 
    engine.seed(seed);
}

用户必须使用try catch来处理错误,否则会调用std::terminate