C++ privately constructed class - c++

How can I call a function and keep my constructor private? If I make the class static, I need to declare an object name which the compiler uses to call the constructor, which it cannot if the constructor is private (also the object would be extraneous). Here is the code I am attempting to use (it is not compilable):
I want to keep the constructor private because I will later be doing a lot of checks before adding an object, modifying previous objects when all submitted variables are not unique rather than creating new objects.
#include <iostream>
#include <fstream>
#include <regex>
#include <string>
#include <list>
#include <map>
using namespace std;
using namespace tr1;
class Referral
{
public:
string url;
map<string, int> keywords;
static bool submit(string url, string keyword, int occurrences)
{
//if(Referrals.all.size == 0){
// Referral(url, keyword, occurrences);
//}
}
private:
list<string> urls;
Referral(string url, string keyword, int occurrences)
{
url = url;
keywords[keyword] = occurrences;
Referrals.all.push_back(this);
}
};
struct All
{
list<Referral> all;
}Referrals;
int main()
{
Referral.submit("url", "keyword", 1);
}

What's wrong with having a private constructor and a static factory method?
class Example {
Example() { ... }
public:
static Example CreateExample() {
return Example();
}
};

Based on your main code I think what you're shooting for is a singleton, which would look something like:
class Referral
{
private:
Referral()
{
//...
}
public:
static Referral& instance()
{
static Referral instance_s;
return instance_s;
}
bool submit(string url, string keyword, int occurrences)
{
//...
}
};
Then your call in main would look like:
int main()
{
Referral::instance().submit("url", "keyword", 1);
}
Another possibility is that you're looking to keep a list of Referrals around, in which case you can use a struct and a list of them to accomplish what you're looking for:
struct Referral
{
Referral(string url, string keyword, int occurrences) :
url_m(url), keyword_m(keyword), occurrences_m(occurrences)
{ }
string url_m;
string keyword_m;
int occurrences_m;
};
typedef std::vector<Referral> ReferralSet;
Then your call in main would look like:
int main()
{
ReferralSet set;
set.push_back(Referral("url", "keyword", 1));
}

First, you need to make Submit a static function. Then you can just say
Referral::Submit( url, keyword, occurrences );
without creating a Referral instance.
Then, in your Submit function, you're only creating a temporary Referral object that disappears almost immediately. Probably what you want to do is create an instance dynamically with new. Depending on how you want to manage this, you may want to move the code pushing onto the list into Submit.
Lastly, I would make your list of Referral instances a static member variable rather than how you have it now.
(Also, passing those string arguments by reference would probably be a good idea.)

While the whole code has some smell around, you can make it work just by making slight changes that are unrelated to your question.
To make it compile, I have removed the regex include (I am not using a compiler with C++0x support) and the 'using namespace tr1'. Move the constructor implementation after the definition of the Referral global object. Change the . for a :: in the main function when you refer to a static method.
// changes...
//#include <regex>
...
//using namespace tr1;
...
class Referral {
...
Referral(string url, string keyword, int occurrences); // added ; moved the implementation bellow the Referrals variable definition
...
struct All {
...
} Referrals;
// added constructor implementation here (Referrals global must be defined before use):
Referral::Referral(string url, string keyword, int occurrences)
{
url = url;
keywords[keyword] = occurrences;
Referrals.all.push_back(*this); // added dereference, this is of type Referral*, not Referral
}
int main()
{
Referral::submit("url","keyword",1);
}
Now, from a design point of view the code has a stench to it. If really want to have a global list where you add your Referral objects, consider making it a private static attribute of the Referral class so that you can have a little more control over it (only methods in the Referral class could break the contents). Make all your attributes private and provide only accessors to the functionality that user code will need (read-only access can suffice in most cases). Use initialization lists in your constructors, and initialize all members there in the same order they appear in the class definition.
With all that fixed, it still has some smell to it. The static function creates an instance of the class but the constructor is the one that includes itself in the map (??) It would make a little more sense if the constructor did not interact with the map, and the submit() method would create the object and then include it in the list...
I think you might benefit from expressing what you intend to do, many people here will help you both with design choices and reasons for them.

Related

c++ passing a vectored class to another class

I am trying to write my code without using global variable as most people told me it was a bad habit, so I am changing how my program works.
I am having problem with passing multiple instance of a class to another class. I need to be able to modify the multiple instance of a class in the other class.
Here is what I am trying to do but failing miserably at it :
int main() {
Players *player[6];
//preparing 6 instances of Players() so I can loop through them in another class
for (int i = 0;i<6;i++){
player[i] = new Players();
}
player[0]->name = "fluffy";
Players.h
#ifndef PLAYERS_H_
#define PLAYERS_H_
#include <string>
#include <vector>
class Players {
public:
Players();
virtual ~Players();
std::string name;
bool hand;
int cif;
int id;
std::vector<int> autho;
std::vector<int> collec;
std::vector < std::vector <int> > puppet;
};
#endif /* PLAYERS_H_ */
Players.cpp
#include "Players.h"
Players::Players() {
// TODO Auto-generated constructor stub
name = "";
hand = false;
cif = -1;
id = -1;
}
Players::~Players() {
// TODO Auto-generated destructor stub
}
Now I want to call another class (doesn't matter which) and I want to pass the multi instanced class Players to it so it can read and do modification to the data within these instanced classes.
For example a class with a function that could read player[0]->name and modify it to "sandpaper"
How would you approach this without getting errors from the compiler?
I am open to suggestion for a completely different way to approach this ( I have tried to use struct variables and pass it but I got other problems as well)
thank you,
Kaven
First of all, I'd approach this by using std::vector<Players> (not pointers!). Secondly, I'd just pass this vector by reference to other functions.
I suggest to approach like this:
int main()
{
unique_ptr<vector<Player>> playersVector (new vector<Player>);
for (int i = 0;i<6;i++)
{
playersVector->push_back(Players());
}
playersVector->at(0).name = "fluffy";
}
And then if you want to pass that vector with ownership to some method or class use:
move(playersVector)
If you want have ownership in main class pass by normal pointer:
playersVector.get()
I also suggest using Get/Set methods instead of accessing class fields directly

Refactoring 3 cyclic classes

I have made a big edit in attempt to clarify what help I am asking for and to try to make the question appropriate for Stack Overflow.
The problem in general: I have an existing library class which allows me to query a server for information. That library class is widely used by a large amount of legacy software, so I am somewhat limited in the changes I can make to it. Likewise, reimplementing it in a better fashion might not be time well spent.
The problem in specific: I've create a simplified "toy" model of my approach below with 3 classes. The real thing is more complex, as there are polymorphic variations, more functionality, error handling, etc.
In "toy" model code included below, Gateway is the existing library class. I've tried to show how I would like to use it, with a result set and a way to access each member of the set. The idea is similar to how a well-implemented database API might look, with a statement, result and row -- except in my case, what would be the statement class is hobbled by a poor design which includes part of the result functionality.
The toy example below will not compile as-is because of the following cyclical dependecy. The Gateway class includes the ResultSet class and depends upon it, as it returns a ResultSet object. The ResultSet class depends on the Member class, as it uses it to convert the data returned from the server into primitives (e.g. string). But the Member class refers back to the Gateway class to access that data, and so there is a cycle.
I want to find a solution which will provide the ResultSet and Member functionality.
For a simpler 2 class problem, I know a solution. It is to create a superclass that one class derives from (is-a), and which the other class is composed of (has-a), such that both original classes depend on the third, and all is right with the world. :-)
For my 3 class problem, for some reason I have been unable to wrap my head around how to refactor it to make it work.
// Gateway.h
#include "ResultSet.h"
class Gateway {
ResultSet exec(string params);
};
// Gateway.cpp
ResultSet Gateway::exec(string p) { ... }
// ResultSet.h
#include "Member.h"
class ResultSet {
ResultSet(); // ctor
int index;
bool next();
string getCurrent(Member member);
};
// ResultSet.cpp
ResultSet::ResultSet() { index = 0; }
bool ResultSet::next() { ++index < length; }
string ResultSet::getCurrent(Member member) { member.fetch(index) }
// Member.h
#include "Gateway.h"
class Member {
Gateway gateway;
string fetch(int i);
};
// Member.cpp
string Member::fetch(int i) { return gateway.sGet(i); }
// Example desired usage of the final API.
main() {
Gateway gate;
ResultSet set;
Member member;
set = gate.exec("...");
while (set.next()) {
cout << set.getCurrent(member) << endl;
}
}
The solution to your issue is to forward declare the overlapping classes in the header files, and then to include their actual .h files from your .cpp implementation files.
For instance, to get around Gateway's dependencies on ResultSet,
// Gateway.h
class ResultSet;
class Gateway {
ResultSet exec(string params);
};
This forward declares the class ResultSet.
Now in Gateway.cpp, we have to provide the actual interface to the compiler. So now we include ResultSet.h.
// Gateway.cpp
#include "ResultSet.h"
ResultSet Gateway::exec(string p) { ... }
We do this for your other cyclic relationships, and you will then have source you can compile and build.
For ResultSet, we will forward declare Member.
// ResultSet.h
class Member;
class ResultSet {
ResultSet(); // ctor
int index;
bool next();
string getCurrent(Member member);
};
And in its implementation file, we will finally include Member's header.
// ResultSet.cpp
#include "Member.h"
ResultSet::ResultSet() { index = 0; }
bool ResultSet::next() { ++index < length; }
string ResultSet::getCurrent(Member member) { member.fetch(index) }
And finally, Member...
// Member.h
class Gateway;
class Member {
Gateway gateway;
string fetch(int i);
};
And of course, Member.cpp must then include Gateway's information.
// Member.cpp
#include "Gateway.h"
string Member::fetch(int i) { return gateway.sGet(i); }
Now there are no cyclic dependencies.

Using class references to modify public members within another class

Since my last question had too much code in it, I tried to make the simplest example of what I'm trying to do. Take this for example,..
#include <iostream>
using namespace std;
class String
{
public:
private:
};
class ClassTwo
{
public:
int memberVariable;
private:
};
class ClassOne
{
public:
ClassOne (ClassTwo&, String&);
~ClassOne();
private:
ClassTwo& classTwoReference;
String& stringReference;
};
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.memberVariable = 3;
}
ClassOne::~ClassOne()
{
}
int main()
{
String stringObject;
ClassTwo classTwoObject;
ClassOne classOneObject (classTwoObject, stringObject);
}
In JUCE, which is the API I'm using to code a VST Plugin, there is a string class that JUCE names "String". I'm not sure exactly what the constructor does, but you can use something like this to create a String object.
String newString("string");
The ClassTwo in my case, is the AudioProcessor class which has a public member variable that I can access from ClassOne like this.
two.memberVariable = 3;
The ClassOne in my case, is a custom Component(I named it PixelSlider) that I'm using in my GUI. It uses a slider listener to check the status of a slider and modify the member variable in ClassTwo(AudioProcessor). I can do this fine using the method above, but the issue is that I want to create as many ClassOne(PixelSlider) objects as I need. I want to pass them a String object that tells them what member variable of ClassTwo(AudioProcessor) to modify. Logically, this would be done by passing a reference to a String object with the same string value as the name of the ClassTwo member variable. Like this,...
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.(string) = 3;
}
This doesn't work in JUCE, but can anybody tell me a way to get this done without having to create a bunch of different classes almost exactly like ClassOne(PixelSlider) that modify different ClassTwo(AudioProcessor) member variables?
If I understand correctly, you're trying to bind a PixelSlider target to a member of AudioProcessor at runtime, which, as you've discovered, can't be done the way you suggest ( two.(string) = 3 ). One way of achieving this binding would be to use the command pattern (http://sourcemaking.com/design_patterns/command/cpp/2).
AudioProcessor could expose a collection of these command objects for each modifiable property ...
AudioProcessorCommand
AudioProcessor::GetCommandByName(String const& properyName) const
{
...
}
... which you can pass to the constructor of PixelSlider. Something along the lines of ...
PixelSlider::PixelSlider(AudioProcessorCommand& command)
: command_{command}
{
...
}
When the PixelSlider's value changes you would invoke the command ...
command_(this->value_);

Using objects and object functions through variables

Background of the program: the user is able to input a string of two words only - a verb and a noun. I tokenize this string into a vector and compare tokens[0] with a vector of allowed verbs, and tokens[1] with a vector of allowed nouns.
Now, I'm trying to find a way to allow only certain verbs to be performed on certain nouns. For example, writing "take book" will give a message (or whatever) saying it's allowed, but writing "take door" would not be. I have so far created a class Object with bool values for each possible verb (eg. within the class Object, I can create an Object book for which m_take = true, or false for an Object door).
However, I'm having trouble associating these objects with the user input. For example, I would like to be able to do something like this:
1) User inputs "verb noun", which go into the tokens vector as tokens[0] and tokens[1].
2) Program checks if the input contains acceptable words (individually).
3) Considering getstat() to be the function to retreive the bool value of the possible action doable on an object, the program retrieves tokens[1].getstat(tokens[0]) and, if true, executes tokens[0].tokens[1]() (eg. book.take()). This way I could have only one if cycle in my main(), which can be used by all legal verbs and nouns, without making an infinite list of if, else if, etc, considering every single option manually.
Sorry if this is at all confusing. I know it is not possible to use a variable as an object name, but I'm sure there's a better way to do this than doing cycles within cycles of considering every single mix and match of verb and noun. I'm experimenting with like 3 each at the moment, but once I get this working I plan on expanding it and it would be a nightmare to keep track of every change if I have to hard-code every possible verb and noun multiple times within the source code. (Also, sorry for not posting the whole source - it's a really long file just now!)
Thanks for any help/hint in the right direction!
You could use runtime polymorphism for this kind of stuff, either with virtual methods or C++11 std::function and lambdas.
You will obviously have to redesign your "token" system.
Virtual methods example:
struct Object
{
virtual void onTake() { }
virtual void onOpen() { }
};
struct Door : public Object
{
bool open{false};
void onTake() override { say("I can't take the door!"); }
void onOpen() override { say("The door is now open."); open = true; }
};
struct Book : public Object
{
void onTake() override { say("I put the book in my backpack."); }
void onOpen() override { say("I open the book. All the pages are blank."); }
};
C++11 lambdas example:
struct Object
{
std::function<void()> onTake, onOpen;
};
struct Door : public Object
{
bool open{false};
Door()
{
onTake = []{ say("I can't take the door!"); };
onOpen = []{ say("The door is now open."); open = true; };
}
};
struct Book : public Object
{
Book()
{
onTake = []{ say("I put the book in my backpack."); };
onOpen = []{ say("I open the book. All the pages are blank."); };
}
};
// You can also avoid creating new classes
Object bananaPrototype;
bool eaten{false};
bananaPrototype.onTake = []{ say("I put the banana in my backpack."); };
bananaPrototype.onOpen = [eaten] mutable
{ say("I eat the banana. Yum."); eaten = true; };
It's hard to give an advice in such a non trivial case not seeing the code, but, as far as I understand, you'd better consider dropping the hardcode approach, i.e.
book.take().
Try writing more generic code, at least something like book.action(actions::kTake).
As you say, tokens[0].tokens[1]() does not do what you want it to - the names of functions and variables are not available when the program is being run.
You could try using maps. objects could be a map with keys of the object names. The values (objects[token[0]]) would in turn be other maps which would be functions to do what you want (objects[token[0]][token[1]]).
Here is an example:
#include <unordered_map>
#include <string>
#include <iostream>
using namespace std;
void read_fn()
{
cout << "You read the book";
}
int main()
{
unordered_map <string, unordered_map <string, void (*)()>> lookup;
unordered_map <string, void (*)()> book_lookup;
book_lookup["read"] = read_fn;
lookup["book"] = book_lookup;
lookup["book"]["read"]();
}

Populate a static member container in c++

I've got a static class member which is some container, like
(Foo.h)
class Foo
{
...
private:
static list<string> s_List;
}
I need to populate the list with a number of specific values. Actually it should be also const, but that might overcomplicate the problem further.
All the class member functions are static, so initializing it in a constructor doesn't make sense.
a common solution is to do something like this:
// header
class Foo
{
...
private:
static list<string> s_List;
}
// cpp
list<string> init()
{
list<string> tmp;
... fill tmp with strings
return tmp;
}
list<string> Foo::s_List(init());
the other method is like Neil Butterworth suggested.
Another alternative is to create a simple initialiser class:
list <string> Foo::s_List;
struct Init {
Init() {
Foo::s_List.insert("apple");
Foo::s_List.insert("bannana");
Foo::s_List.insert("grapes");
}
};
static Init doInit;
Note that, as the list is private, this will probably require you to make Init a friend of Foo. It's also often convenient to make such classes be contained by the class they are initialising.
However, I just re-read your question and another thought occurs - if the list is const, you will presumably not be changing it, in which case a simple array of strings, initialised with the strings in sorted order may be a better solution. It will certainly be faster to search (using std::binary_search) than a list, and can of course be easily initialised.
If your compiler supports C++0x, this is actually trivial to accomplish.
#include <iostream>
#include <list>
class Foo
{
public:
static std::list<std::string> s_List;
};
std::list<std::string> Foo::s_List = {"hello", "world", "asdf", "qwerty"};
int main()
{
for(const std::string& str : Foo::s_List)
std::cout << str << std::endl;
return 0;
}
This works for both const and non-const static members. I've tested this snippet with clang-4.2, gcc-4.7, gcc-4.6, and gcc-4.5. Gcc-4.5 does not support the updated for syntax, so you'd have to use a traditional for loop with iterators. Also, don't forget to pass the -std=c++0x flag to the compiler. I'm reasonably confident Visual Studio supports this as well, but I don't know for sure and don't know which versions.
It depends on what values you need to put in that list. Are they static or do they require some form of computation?
If they are static, you can do this:
namespace {
const char* const initVals[] = { "A", "B", "C" };
}
list<string> Foo::s_list(initVals, initVals + 3);
one possible solution would be to use an accessor method that checks to see if it is initialized, and does so if it isn't.
The ways I(the author of the question) have vainly tried to do this.
I tried to do smth like (in Foo.cpp):
list<string> Foo::s_List = list<string>();
Foo::s_List.insert("apple");
Foo::s_List.insert("bannana");
Foo::s_List.insert("grapes");
But that gives a compiler error.
Then I thought of making an Initialize() method and calling it right from the code
void Foo::Initialize()
{
s_List.insert("rats");
s_List.insert("cats");
}
Foo::Initialize();
// error: compiler considers it to be a redefenition of the method, not a call.
The only viable idea left (havent yet tried) would be to check if the list is empty in each method that uses it, and if it's the case, call Initialize(). But that's ugly!