开发者

How should I handle Inconsistent Objects in C++?

Say, I want to create a File class

class File{
    public:
          File(const char *file){
               openFile(file);
          }
          ~File();
          isEmpty();
};

openFile checks if the file exists or if the contents of the file are valid or not.

File *file = new File("filepath");
if(file)
file->isEmpty();
开发者_JS百科

if my filepath is correct, then all fine, file instance is proper and we can invoke file->isEmpty(); What is the file does not exist, in that case still the check if(file) evaluates to true and will lead to creation of file instance which is actually invalid. How can i guarantee that if file path is invalid, the file instance should be null.


Your constructor should throw an exception in the case that the file couldn't be opened.

File::File( const char* pPath )
{
  if ( !openFile( pPath ) )
    throw FileNotFound( pPath );
}


The only way to do checking like that in the constructor is to throw an exception. But that's not considered good design - you should create it, check if it's valid, and delete it if it isn't.


I suggest using a static factory method that does the check for you and if the object is invalid deletes it and throws an exception. You would create the file like this:

File* file = File::open("whatever");


If I understand what you correctly, you want to return null from the constructor when "filepath" is invalid? This isn't (directly) possible in C++, although there are a few possibilities. You could throw an exception from your constructor, but this can get hairy in C++. You could have some functions that can check the validity of a File object, so if(file) would become if(isValid(file)). You could also wrap some of this logic in some sort of factory that would return null if the file to be created is invalid.


I would use the STL, templates and throw an empty class. Now, you can't return anything from a constructor... so either do something like this:

#include <string>
using std::basic_string;

class EmptyFile{};

template<typename T>
    class File
    {
    public:
        File(const basic_string<T> &FILE)
        {
            if (isEmpty(FILE)) throw EmptyFile();
            openFile(FILE);
        }
        bool isEmpty(const basic_string<T> &FILE) const
            { return FILE.empty(); }
    };

or you could do this:

#include <string>
using std::basic_string;

template<typename T>
class File
{
public:
    bool Open(const basic_string<T> &FILE) const
    {
        bool empty = isEmpty(FILE);
        if(!empty)
           /* open the file */;
        return isEmpty;
    }
    bool isEmpty(const basic_string<T> &FILE) const
    { return FILE.empty(); }
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜