Looks reasonable to me. I think pointers are fine if you can be confident the data source and options source are alive during the lifetime of the algorithm. I don't think pointers are unavoidable though. Here are few other options (some of which are C++11):
References
Preferably const references. Possibly a bit safer than pointers if you are passing them in the constructor and you don't need them to be nullable.
BaseAlgorithm(BaseDataSource& dataSrc,
BaseOptionsSource& optsSrc) :
dataSrc_(dataSrc),
optsSrc_(optsSrc) {}
Shared smart pointers
If you can't be confident that the data source or options source are alive for the lifetime of the algorithm consider passing in a std::shared_ptr
or std::weak_ptr
. Use std::shared_ptr
if you want to keep them alive, std::weak_ptr
if you want to know if they are alive.
BaseAlgorithm(std::weak_ptr<BaseDataSource> dataSrc,
std::weak_ptr<BaseOptionsSource> optsSrc) :
dataSrc_(dataSrc),
optsSrc(optsSrc) {}
Sink
It depends on how these data sources, options sources and algorithms are created and used but maybe it will make ownership simpler if the algorithm takes ownership of the data source and/or options source and pass by unique_ptr.
BaseAlgorithm(std::unique_ptr<BaseDataSource> dataSrc,
std::unique_ptr<BaseOptionsSource> optsSrc) :
dataSrc_(std::move(dataSrc)),
optsSrc(std::move(optsSrc)){}
A few minor points: I question if an out parameter is the best way of getting options and data chunks. Don't be afraid of return-by-value even for something large like a data chunk The copy will always be optimized away by any modern compiler and it makes the calling code easier to read and write:
Options opts = optsSrc_->GetOptions(opts);
DataChunk data = dataSrc_->GetDataChunk(data);
You may have missed them out to simplify your post but I wonder if GetOptions
and/or GetDataChunk
can be const
? Should calling them make changes to the source? If they can be const
it means the algorithms only need a const pointer/reference to the source and it might make finding errors slightly easier. You talk about re-using source objects, this may not be wise if the algorithms can make changes to the source objects. For example what happens if you call GetDataChunk repeatedly, do you get a different chunk each time? This might have unexpected consequences if you can use the same data source in different algorithms.
Lastly, make sure _pOptsSrc and _pDataSrc are protected
or private
not public.