Mushy
Mushy

Reputation: 2655

Java-like null for string and ofstream arguments in c++

I have some Java code (constructor)

RecursiveDescentParser
(
  std::string inputStream, 
  bool fileService, 
  std::string filePathName, 
  std::ofstream writer
)
{
  input_ = inputStream;
  tokenizer_ = new Tokenizer(inputStream);
  if (fileService == true){
      error = new ErrorHandling(fileService, std::move(writer));
  }
  else{
      error = new ErrorHandling(fileService, std::ofstream());
  }     
  compiled_ = "";
}

Tokenizer *tokenizer_;

std::string input_, compiled_;

I would like to emulate a call within c++

RecursiveDescentParser *parser = new RecursiveDescentParser
(
  stream, 
  false, 
  null, 
  null
);

If I use pointer arguments

std::string *str; std::ofstream *out

I can pass in nullptr but if I choose not to use pointer arguments, I can't pass null. What can I do to simulate passing null to a std::string and std::ofstream?

Upvotes: 0

Views: 201

Answers (4)

Mike Seymour
Mike Seymour

Reputation: 254631

Pointers are one option as you say; but create complications as you need to either manage the objects separately, or use smart pointers. Shared pointers are a possibility, and give semantics quite similar to Java's object references (only with reference counting rather than garbage collection).

For a nullable object type, you could use Boost.Optional, or implement your own nullable wrapper class. There is talk of optional being included in a future standard library; but for now, you need Boost for that.

Alternatively, it might make more sense to provide a second constructor which does not take those arguments at all.

Upvotes: 2

Dmytro
Dmytro

Reputation: 5213

sadly, strings in C++ are objects, and unlike java, C++ objects cannot be null.

From what I understand, you are creating a constructor to a RecursiveDescentParser. The constructor's job is to initialize the object.

If the constructor was allowed to accept a pointer, it could accept a null path string, then it will have been created with a null path string, because it is constructor's job is to initialize all fields, and null fields are not initialized, this would not be a good solution.

My suggestion is to make the constructor private, but create a public method that can accept the parameters the constructor would, but also a pointer to the string rather than the object. If the path string pointer is null, throw an exception, or return an error object. If the path string is valid, create a new parser from reference to the string pointed to by path string pointer, and return this reference.

Although, I could be totally off, but this is just a suggestion, and I welcome all constructive criticisms on why this would not work.

Upvotes: 0

metalhead
metalhead

Reputation: 567

This is how I would change your usage:

RecursiveDescentParser
(
  std::string inputStream, 
  bool fileService = false, 
  std::string filePathName = "", 
  std::ofstream* writer = NULL
)

RecursiveDescentParser *parser = new RecursiveDescentParser(stream);

Upvotes: 1

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70989

You have two options - either create a wrapper class that represents an optional value or use pointers. I strongly recommend the first option.

Also in some cases you may considered an empty string to be equivalent to not set value.

Upvotes: 0

Related Questions