I have a class that contains an std::ofstream and an std::ifstream (only one can be activated at a time). I would like to overload the operator() to return the current active stream. But what is the common base type of std::ofstream and std::ifstream to return a common reference ?
I would like to overload the operator() to return the current active stream This makes absolutely no sense and smells like a design flaw. Why do you want to return that? What should the caller of that operator be able to do with return value? It can neither do input nor output.
I dunno what you really want to do, but perhaps something like this could work for you, though it's dangerous
template<typename T> class wrapper
{
T*const ptr;
wrapper(T*p) : ptr(p) {}
public:
bool empty() const { return ptr; }
operator T& () const
{
if(empty()) throw some_exception("trying to use empty wrapper");
return *ptr;
}
friend some_class;
};
class some_class
{
ifstream _ifstream;
ofstream _ofstream;
bool ifstream_is_active;
bool ofstream_is_active;
public:
operator wrapper<ifstream> () const
{ wrapper<ifstream>(ifstream_is_active? &_ifstream : 0); }
operator wrapper<ofstream> () const
{ wrapper<ofstream>(ofstream_is_active? &_ofstream : 0); }
};
but this is dangerous, as you are potentially dealing with dangling pointers. You can avoid that by using shared_ptr (work this out yourself), but that means that some_class has no longer control over the lifetime of these streams.
Input and output streams are very different types. The only common base class they share is std::ios. And that doesn't have much in it besides some error checking stuff.
The two stream types only share the most basic of interfaces. They have little to do with one another, for obvious reasons.
Related
I am trying to implement lazy initializing in C++ and I am searching for a nice way to call the Initialize() member function when some other method like object->GetName() gets called.
Right now I have implemented it as follows:
class Person
{
protected:
bool initialized = false;
std::string name;
void Initialize()
{
name = "My name!"; // do heavy reading from database
initialized = true;
}
public:
std::string GetName()
{
if (!initialized) {
Initialize();
}
return name;
}
};
This does exactly what I need for the time being. But it is very tedious to setup the initialized check for every method, so I want to get rid of that. If someone knows a nice way in C++ to improve this above example, I would like to know!
Could maybe operators be used to achieve calling Initialize() when using -> for example?
Thanks!
Sounds like a job for templates! Create a lazily_initialized wrapper that takes a type T and a function object TInitializer type:
template <typename T, typename TInitializer>
class lazily_initialized : TInitializer
{// ^^^^^^^^^^^^^^
// inheritance used for empty-base optimization
private:
T _data;
bool _initialized = false;
public:
lazily_initialized(TInitializer init = {})
: TInitializer(std::move(init))
{
}
T& get()
{
if(!_initialized)
{
static_cast<TInitializer&>(*this)(_data);
_initialized = true;
}
return _data;
}
};
You can the use it as follows:
struct ReadFromDatabase
{
void operator()(std::string& target) const
{
std::cout << "initializing...\n";
target = "hello!";
}
};
struct Foo
{
lazily_initialized<std::string, ReadFromDatabase> _str;
};
Example:
int main()
{
Foo foo;
foo._str.get(); // prints "initializing...", returns "hello!"
foo._str.get(); // returns "hello!"
}
example on wandbox
As Jarod42 mentioned in the comments, std::optional<T> or boost::optional<T> should be used instead of a separate bool field in order to represent the "uninitialized state". This allows non default-constructible types to be used with lazily_initialized, and also makes the code more elegant and safer.
As the former requires C++17 and the latter requires boost, I used a separate bool field to make my answer as simple as possible. A real implementation should consider using optional, using noexcept where appropriate, and also consider exposing a const-qualified get() that returns a const T&.
Maybe call it in the constructor?
Edit: Uh, i missed the point of your question sorry.
What about a lazy factory initialization?
https://en.wikipedia.org/wiki/Lazy_initialization#C.2B.2B
I wrote this template class for pointers usage
(I need smart pointers, but I can't use boost or C++11):
template<class T>
class TreePointer{
public:
TreePointer(){
isRefOnly=false;
data=NULL;
};
TreePointer(T* data){
this->data=data;
this->isRefOnly=false;
}
TreePointer(const TreePointer& anotherPtr){
this->data=anotherPtr.data;
this->isRefOnly=true;
}
virtual ~TreePointer(){
if (!isRefOnly){
delete data;
}
}
T* operator->() const{
return data;
}
void operator=(const TreePointer &anotherPtr){
this->data=anotherPtr.data;
this->isRefOnly=true;
}
private:
T* data;
bool isRefOnly;
};
And I have big class with many methods, like this:
class WrittenBigClassWithManyMethods{
public:
WrittenBigClassWithManyMethods(int v){
this->v=v;
}
int sum(WrittenBigClassWithManyMethods* a){
return v+a->v;
}
int v;
};
This usage of my smart pointers work perfectly:
TreePointer<WrittenBigClassWithManyMethods> tp(new WrittenBigClassWithManyMethods(5));
WrittenBigClassWithManyMethods* simpleClass=new WrittenBigClassWithManyMethods(5);
cout << tp->sum(simpleClass);
But it usage isn't work:
TreePointer<WrittenBigClassWithManyMethods> tp2(new WrittenBigClassWithManyMethods(5));
cout << tp->sum(tp2);
How i can change my template for pointers to make invoking methrod sum of class WrittenBigClassWithManyMethods with parameter of type TreePointer, without any changes for class WrittenBigClassWithManyMethods and its any usages? If this is not possible, how I minimize the changes for class WrittenBigClassWithManyMethods and its usage?
Usually you'll want to overload the unary operator * (de-reference) too, returning a T&. Then you can have both a reference and the original pointer by taking the address of the result:
tp1->method_that_takes_ref(*tp2); // With operator*()
tp1->method_that_takes_ptr(&*tp2); // Works, but syntax might be a bit surprising
Another way to get at the pointer inside would be to call operator -> directly, but that would be a bit awkward. You are likely better off providing some kind of "get" method, like the one in unique_ptr, that simply returns the raw pointer:
tp1->method_that_takes_ptr(tp2.operator->()); // Works, but ugh
tp1->method_that_takes_ptr(tp2.get()); // Much clearer
Add a conversion operator to T*:
operator T*() {
return data;
}
Now the compiler will call it whenever it wants to convert a TreePointer<SomeClass> to a SomeClass*.
I want to throw an exception in my constructor so that I don't have to deal with zombie objects. However I also want to provide a validation method upfront so that people can avoid "dealing with exceptions" where there is no cause to. In a GUI it's not exceptional to expect invalid data. However I also want to avoid code duplication and overhead. Is GCC / Microsoft Visual C++ compiler smart enough to remove this inefficiency of validating an input twice and if not, is there a subtle change that could please?
An example code block illustrating my point is below:
#include <string>
#include <exception>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
using std::exception;
// a validation function
bool InputIsValid(const string& input) {
return (input == "hello");
}
// a class that uses the validation code in a constructor
class MyObject {
public:
MyObject(string input) {
if (!InputIsValid(input)) //since all instances of input
throw exception(); //has already been validated
//does this code incur an overhead
//or get optimised out?
cout << input << endl;
};
};
int main() {
const string valid = "hello";
if (InputIsValid(valid)) {
MyObject obj_one(valid);
MyObject obj_two(valid);
}
return 0;
}
I anticipate this may not be possibly if the object file for the class is generated alone as the object file has no way to ensure people will validate before calling the constructor, but when an application is compiled and linked together in a single application, is it possible please?
Is there an overhead of validating in a constructor if all data may already be valid?
Yes, if the data is already validated, then you would incur the cost of validating it again
Is GCC / Microsoft Visual C++ compiler smart enough to remove this inefficiency of validating an input twice and if not, is there a subtle change that could please?
You could encapsulate your input in an object, and that object would remember the result of validation.
template <typename INPUT_TYPE>
class InputObject {
INPUT_TYPE input_;
bool valid_;
public:
typedef <typename VALIDATE>
InputObject (INPUT_TYPE in, VALIDATE v) : input(in), valid_(v(in)) {}
const INPUT_TYPE & input () const { return input_; }
bool isValid () const { return valid_; }
};
typedef InputObject<std::string> MyInput;
class MyObject {
public:
MyObject (const MyInput &input) {
if (!input.isValid()) throw exception();
//...
}
};
The constructor to InputObject calls the validator function for you, and stores the result of validation in a flag. Then MyObject just checks the flag, and doesn't have to do the validation again.
int main () {
MyInput input("hello", InputIsValid);
try {
MyObject obj_one(input);
MyObject obj_two(input);
}
catch (...) {
//...
}
}
As suggested by DeadMG, stronger type checking can be achieved by insisting that MyObject only accept validated input. Then, it would not need to throw in the constructor at all. Such a scheme could be accomplished by making NonValidatedInput and ValidatedInput two different types.
template <typename> class NonValidatedInput;
template <typename T>
class ValidatedInput {
friend class NonValidatedInput<T>;
T input;
ValidatedInput (const T &in) : input(in) {}
public:
operator const T & () const { return input; };
};
template <typename T>
class NonValidatedInput {
T input;
public:
operator ValidatedInput<T> () const { return ValidatedInput<T>(input); }
template <typename V>
NonValidatedInput (const T &in, V v) : input(in) {
if (v(input) == false) throw exception();
}
};
NonValidatedInput accepts non-validated input, and performs the validation, and can be converted to a ValidatedInput object if the validation succeeds. If the validation fails, NonValidatedInput throws an exception. Thus, MyObject has no need to check for validation at all, because it's constructor only accepts ValidatedInput.
typedef ValidatedInput<std::string> MyInput;
class MyObject {
public:
MyObject (MyInput input) {
std::string v = input;
std::cout << v << std::endl;
}
};
int main () {
try {
MyInput input = NonValidatedInput<std::string>("hello", InputIsValid);
MyObject obj_one(input);
MyObject obj_two(input);
}
catch (...) {
//...
}
}
The type safety here is quite strong, because only NonValidatedInput can create a ValidatedInput, and only if the validation succeeded.
the optimizer may inline the function InputIsValid(), however that's about as far as it will go. You also need to document your constructor as throwing, with the types of exceptions its going to throw. As far as the performance costs of calling that function,it's negligible, the cost of a strcmp(). Suffice to says though unless that constructor is used in an extremely tight loop that the costs should be negligible.
I'm trying to make a simple logger class, and I want the ability to either log to either a generic ostream (cout/cerr) or a file. The design I have in mind is to allow the constructor to either take an ostream& or a filename, and in the latter case create an ofstream& and assign that to the class' private ostream& like so:
class Log {
private:
std::ostream& os;
public:
Log(std::ostream& os = std::cout): os(os) { }
Log(std::string filename) {
std::ofstream ofs(filename);
if (!ofs.is_open())
// do errorry things
os = ofs;
}
};
Doing such gives me an error that ofstream's assignment operator is private. Looking over that again, it occurred to me that making a reference to a local object probably wouldn't work, and making os a pointer to an ostream and declaring and deleting it on the heap worked with the ofstream case, though not with the ostream case, where the ostream already exists and is just being referenced by os (because the only place to delete os would be in the constructor, and I don't know of a way to determine whether or not os is pointing to an ofstream created on the heap or not).
So how can I make this work, i.e. make os reference an ofstream initialized with a filename in the constructor?
For one thing, you can't rebind references once they're created, you can only initialise them. You might think you could do this:
Log(std::string filename) : os(std::ofstream(filename)) {
if (!os.is_open())
// do errorry things
}
But that's no good because you are making os refer to a temporary variable.
When you need a reference that has to be optional, that is, it needs to refer to something sometimes and not other times, what you really need is a pointer:
class Log {
private:
std::ostream* os;
bool dynamic;
public:
Log(std::ostream& os = std::cout): os(&os), dynamic(false) { }
Log(std::string filename) : dynamic(true) {
std::ofstream* ofs = new std::ofstream(filename);
if (!ofs->is_open())
// do errorry things and deallocate ofs if necessary
os = ofs;
}
~Log() { if (dynamic) delete os; }
};
The above example is just to show you what is going on, but you probably will want to manage it with a smart pointer. As Ben Voigt points out, there are a lot of gotchas that will cause unforeseen and undesired behaviour in your program; for example, when you try to make a copy of the above class, it will hit the fan. Here is an example of the above using smart pointers:
class Log {
private:
std::unique_ptr<std::ostream, std::function<void(std::ostream*)>> os;
public:
Log(std::ostream& os = std::cout): os(&os, [](ostream*){}) { }
Log(std::string filename) : os(new std::ofstream(filename), std::default_delete<std::ostream>()) {
if (!dynamic_cast<std::ofstream&>(*os).is_open())
// do errorry things and don't have to deallocate os
}
};
The unusual os(&os, [](ostream*){}) makes the pointer point to the given ostream& but do nothing when it goes out of scope; it gives it a deleter function that does nothing. You can do this without lambdas too, it's just easier for this example.
The simplest thing to do is just bind your reference to an ofstream, and make sure the ofstream lives as long as your object:
class Log
{
std::ofstream byname;
std::ostream& os;
public:
Log(std::ostream& stream = std::cout) : byname(), os(stream) { }
Log(std::string filename) : byname(filename), os(this->byname)
{
if (!os)
// handle errors
}
};
Exception safe, can't leak, and the compiler-generated special member functions are sane.
In my Log/Debug class I find it useful to create a static member variable:
class debug {
public:
...
// Overload operator() for printing values.
template<class Type1>
inline debug&
operator()(const std::string& name1,
const Type1& value1)
{
// Prettify the name/value someway in another inline function.
_stream << print_value(name1, value1) << std::endl;
return *this;
}
private:
...
static std::ostream& _stream;
};
And then in my debug.cc file:
std::ostream& debug::_stream = std::cerr;
You have to initialize the os in the initialize list in the constructors, just as what you did in Log(std::ostream& os = std::cout): os_(os) { }, because os is a reference, which can not be assigned after initialized.
Let me say we have a simple programming task. But for the sake of clarity I start with few code samples.
First of all we written a some kind of data container class but for the purposes of task no matter what the class is. We just need it to behave const-correct.
class DataComponent {
public:
const std::string& getCaption() const {
return caption;
}
void setCaption(const std::string& s) {
caption = s;
}
private:
std::string caption;
};
Then let us assume we've got a generic class that behaves like facade over arbitrary incapsulated class instance. Say we overloaded member access operator (->).
template <typename T> class Component {
public:
Component() { instance = new T(); }
...
const T* operator-> () const {
return instance;
}
T* operator-> () {
// but there might be additional magic
return instance;
}
private:
T *instance;
};
At this point I should say how I want this to work:
if we're calling non-const member functions of underlying class through member access operator (component->setCaption("foo")) compilier treats non-const T* operator-> () as the best choice.
otherwise if we are trying to call const member functions of underlying class same way (component->getCaption()) compiliers selects const T* operator-> () const on the other hand.
This code sample above won't work this way so I'm curious about possibility to give compiler a behavior like that I have mentioned. Any propositions.
EDIT: Let our member access operator overloaded this way:
const T* operator-> () const { return instance; }
T* operator-> () {
cout << "something going change" << endl;
return instance;
}
And let us have a variable Component<DataComponent> c somewhere. Then on the call to c->getCaption() stdout should remain silent but on the call to c->setCaption("foo") stdout should warn us that something is going to change. VS 2010 compilier makes stdout warn us on each of these calls.
I understand that such semantics suppose that c behaves as const and non-const at the same time. But curiousity is still in my mind.
Whether a const or non-const member is invoked is determined purely by the constness of the object on which it is invoked, not by some subsequent operation. That determination is made before any consideration of the particular method you're invoking in DataComponent. You could still hack up the required functionality less directly using proxy object around DataComponent, with both const and non-const forwarding getCaption()s.
EDIT: details as requested (off the top of my head). You'll need to forward declare some of this stuff - I didn't bother as it makes it even more confusing. Do chip in with any concerns / feedback. Note that this basically assumes you can't / don't want to modify Component for some reason, but it's not a generic templated solution that can simply be wrapped around any arbitrary type - it's very heavily coupled and has a high maintenance burden.
// know they can't call a non-const operation on T, so this is ok...
const T* Component::operator->() const { return instance; }
// they might invoke a non-const operation on T, so...
DataComponent::Proxy Component::operator->() { return DataComponent.getProxy(*this); }
in class DataComponent:
struct Proxy
{
Component& c_;
DataComponent& d_;
Proxy(Component& c, DataComponent& d) : c_(c), d_(d) { }
const std::string& get_caption() const { return d_.get_caption(); }
void set_caption(const std::string& s)
{
c_.on_pre_mutator(d_);
d_.set_caption(s);
c_.on_post_mutator(d_);
}
};
then
DataComponent::Proxy DataComponent::getProxy(Component& c) { return Proxy(c, *this); }
So, this means somewhere you have to hand-code forwarding functions. It's a pain, but if you're doing this for debugging or testing it's not unreasonable. If you're doing this so you can add a lock or something, then there are probably better alternatives.