Static class object - c++

Why are static class objects allowed in C++? what is their use?
#include<iostream>
using namespace std;
class Test {
static Test self; // works fine
/* other stuff in class*/
};
int main()
{
Test t;
getchar();
return 0;
}

This just works; the compiler doesn't have to do anything special simply because self is both a static member of Test and is of type Test. I see no reason why this special case would need to be specifically prohibited.
Now, there is a problem with Test::self in that you declare the variable, but fail to define it. However, this is simply a bug in your code and is easily fixed:
class Test {
...
};
Test Test::self; // <--- the definition
int main()
{
...

You use it for things that are shared between all instances of the class. For example, you can use it to implement the Singleton pattern.

Related

Functions out of scope error C++

My code has a class compROS. I have created 2 functions requestStart and requestNotStart which are trying to call is_started_ and sec_ from class compROS. Now whenever I run the code, I get the following errors:
functions requestStart and requestNotStart and is_started_ and sec_ were not declared in this scope.
My assumption is that the private functions are not accessible from the outside of the class. Should I add requestStart and requestNotStart as friend functions??
What is the most efficient way of tackling these errors?
Following is my code -
(Updated my code based on the comments from #Snps and #Philip Brack)
using namespace std;
namespace Lib
{
class compROS
{
public:
compROS(string error_text, int sec):
error_text_(error_text),
is_started_(false),
sec_(sec)
{
}
private:
string error_text_;
bool is_started_;
int sec_;
};
}
int requestStart(Lib::compROS& c)
{
if(!c.is_started_)
sec_ = 2;
// Start timer
// Timer expired
c.is_started_ = true;
return 0;
}
int requestNotStart(Lib::compROS& c)
{
// <Code to be inserted>
return 0;
}
int main (int argc, char **argv)
{
Lib::compROS c("error", 2);
requestStart(c);
requestNotStart(c);
return 0;
}
int compROS::requestStarted() { } after the class definition will scope the member function to your object. Your issue is that you are declaring a function but not binding it to compROS class so you cannot access the instance members.
When you create a class in c++, what is usually included are the functions that this class will use(or may use), as well as the variables it needs in order to runs those functions. In your case, your requestStart() and requestNotStart() functions are not included in your compROS class as you don't have the actual function calls in your class. This is why when you try to run your program, your functions requestStart() and requestNotStart() are trying to find the variables is_started_ and sec_ but does not find it since those variables only exist INSIDE the class whereas your functions are OUTSIDE of your class. My suggestion is to put the function signature for both the requestStart() and requestNotStart() method in public: and simplify your compPOS method by only using the function signature and actually implement the method outside of the class.
In object-oriented programming, a class definition is like a blueprint of a house. You can not use the kitchen, nor the bathroom, of the blueprint, the only thing you can do is to use it to build a house.
In the same way, you can not call any methods of your class until you have built an instance of that class.
Lib::compROS c("my error", 2);
Any function that wants to call any of your class' methods needs to know on what instance to make the call. You need to somehow pass a reference to an instance of your function.
int requestStart(Lib::compROS& c) {
if(!c.is_started_)
sec_ = 2;
// Start timer
// Timer expired
c.is_started_ = true; // This member needs to be public for external access.
return 0;
}
int main() {
Lib::compROS c("my error", 2); // Create instance.
requestStart(c); // Pass instance to function.
}

Add a method to existing C++ class in other file

Is it possible in C++ to extend a class(add a method) in a different source file without editing the original source file where the class is written?
In obj-c it is possible by writing another #interface AbcClass (ExtCategory) ... #end
I got compile-time error(s) when I tried something like this:
//Abc.h
class Abc { //This class is from a 3rd party library....
// ...I don't want to edit its source file.
void methodOne();
void methodTwo();
}
//Abc+Ext.h
class Abc { // ERROR: Redefinition of 'Abc'
void methodAdded();
}
My target is to retain the 'Abc' name and add methods to it. A specific class in a 3rd party library that I used lacks some methods and I want to add those methods but I am keeping the source file unedited.
Is there a way to do this? I am new in writing C++ codes. I am familiar with some of its syntax but don't know much.
No. This kind of class extension is not possible in C++. But you can inherit a class from the original source file and add new functions in your source file.
//Abc.h
class Abc {
void methodOne();
void methodTwo();
};
//Abc+Ext.h
class AbcExt : public Abc {
void methodAdded();
};
You can then call methods as following:
std::unique_ptr<AbcExt> obj = std::make_unique<AbcExt>();
obj->methodOne(); // by the virtue of base class
obj->methodAdded(); // by the virtue of derived class
There's a way to actually do this, but it requires the compiler to support #include_next. GCC has this, no idea about other compilers. It also needs to support at least C++11.
I wouldn't exactly call this trick beautiful, but it does the job.
Ensure your include path has the the directory where the "extension" file resides before the directory where the original code resides (i.e. if the original Abc.hpp is in src, then move it to src/some_dir). So in this case your include dirs would be -Isrc -Isrc/some_dir.
Your "extension" code should be in a file with the exact same name as the original code. So for this example that's Abc.hpp.
Here's the extension file's content:
#ifndef ABC_EXT_HPP_
#define ABC_EXT_HPP_
#include <utility>
namespace evil {
// Search the include path for the original file.
#include_next "Abc.hpp"
}
class Abc : public evil::Abc {
public:
/*
// Inherit all constructors from base class. Requires GCC >=4.8.
using evil::Abc::Abc;
*/
/* Use the solution below if your compiler supports C++11, but not
* inheriting constructors.
*/
template <class... Args>
Abc (Args... args) : evil::ABC(std::forward<Args...>(args...)) { }
~Abc () { }
void methodAdded () { /* Do some magic. */ }
};
#endif // ABC_EXT_HPP_
There's things missing in the example such as the assignment operator not being "forwarded" to the base class. You can use the same trick as used for the constructor to do that. There might be other things missing, but this should give you a starting point which works well enough for "simple" classes.
One thing I dislike is the creation of the "evil" namespace. However, anonymous namespaces can't help out here, because a new anonymous namespace will be created in each translation unit that includes Abc.hpp. That will lead to issues if your base class has e.g. static members.
Edit: Nevermind, the assignment operator (i.e. Abc bla = evil::Abc(9)) also works, because evil:Abc can be implicitly converted to Abc because that constructor exists.
Edit 2: You might run into a lot of trouble once there's nested namespaces involved. This happens as soon as there's an #include in the original Abc.hpp, because it will now be nested inside the evil namespace. If you know all of the includes, you could include them before declaring the evil namespace. Things get real ugly, real quick though.
There's no specific mechanism for doing this directly in the current C++, but there are several ways you can achieve something like it at the cost of some boiler-plate work:
Method 1:
// foo.h
class Foo {
private: // stuff
public: // stuff
private:
// All this crap is private. Pretend like I didn't expose it.
// yeah, I know, you have to compile it, and it probably adds
// dependencies you don't want to #include, like <string>
// or boost, but suck it up, cupcake. Stroustrup hates life.
void internalHelper(std::string&, std::vector&, boost::everything&);
};
Method 2:
// foo.h
class Foo {
private: // stuff
public: // stuff
};
// fooimpl.h
// Internal file, do not export with the API.
class FooImpl : public Foo {
private: // stuff
public: // stuff
// So yeah, you have to go thru a cast and an extra include
// if you want to access this. Suck it up, cupcake.
void internalHelper(std::string&, std::vector&, boost::everything&);
};
Method 3:
// foo.h
class Foo {
private: // stuff
public: // stuff
// For the private api: this is the worst approach, since it
// exposes stuff and forces include/cruft on consumers.
friend void foo_internalHelper(std::string&, std::vector&, boost::everything&);
};
// foo.cpp
// don't make it static or anyone can make their own as a way to
// back door into our class.
void foo_internalHelper(...);
Method 4:
// foo.h
class Foo {
private: // stuff
public: // stuff
// No dependencies, but nothing stops an end-user from creating
// a FooPrivate themselves...
friend class FooPrivate;
};
// foo1.cpp
class FooPrivate {
public:
void fooInternalHelper(Foo* f) {
f->m_privateInternalYouCantSeeMe = "Oh, but I can";
}
};
You cannot extend the class Abc, period!
The only way out are freestanding functions like
Abc add(const Abc& a, int b);
i found out that c++ is better at doing this than obj-c.
i tried the following and it works great!
the key is, enclose all of your classes in a namespace and then extend your target classes there with the same class name.
//Abc.h
namespace LibraryA {
class Abc { //This class is from a 3rd party library....
// ...I don't want to edit its source file.
void methodOne();
void methodTwo();
}
}
//Abc+Ext.hpp
namespace MyProj {
class Abc : public LibraryA::Abc {
using Base = LibraryA::Abc; //desc: this is to easily access the original class...
// ...by using code: Abc::Base::someOrigMethod();
using Base::Base; //desc: inherit all constructors.
protected:
//---added members:
int memberAdded;
public:
//---added methods:
void methodAdded();
//---modified virtual member funcs from original class.
void origMethod_A() override;
}
}
//Abc+Ext.cpp
namespace MyProj {
void Abc::origMethod_A() {
//...some code here...
Base::origMethod_A(); //desc: you can still call the orignal method
//...some code here...
}
}
//SomeSourceFile_ThatUses_Abc.cpp
namespace MyProj { //IMPT NOTE: you really need to enclose your...
// ...project specific code to a namespace so you can...
// ...use the version of class Abc you extended.
void SomeClass::SampleFunc(){
Abc objX; //create MyProj::Abc object.
objX.methodAdded(); //calls MyProj::Abc::methodAdded();
objX.origMethod_A(); //calls MyProj::Abc::origMethod_A();
Abc::Base objY; //create Library::Abc object.
//objY.methodAdded(); //method not existing.
objY.origMethod_A(); //calls Library::Abc::origMethod_A();
//...some code here...
}
}
//SomeModule.cpp
namespace OtherNamespace {
void SomeOtherClass::SampleOtherFunc(){
Abc objZ; //create Library::Abc object.
//objZ.methodAdded(); //method not existing.
objZ.origMethod_A(); //calls LibraryA::Abc::origMethod_A();
}
}
you can even extend class Abc differently within other module namespaces.
//MyLib_ModuleA_Classes.hpp
namespace MyLib_ModuleA {
class Abc : public LibraryA::Abc {
//...add extensions here...
void addedMethod_X();
void origMethod_A() override; //own overriden behavior specific to this ModuleA only.
}
}
//MyLib_ModuleB_Classes.hpp
namespace MyLib_ModuleB {
class Abc : public LibraryA::Abc {
//...add extensions here...
void addedMethod_Y();
void origMethod_A() override; //own overriden behavior specific to this ModuleB only.
}
}
if in case class Abc is in global namespace, though i haven't tried it yet, i think you can just replace LibaryA::Abc to ::Abc.
sorry for the very late answer i've been doing this approach for around 4 years now and it's structure is very well useful.
i tried this in c++14 but i think this is still doable in c++11. now i used c++17 and it compiles fine. i'm planning to convert to c++20
when the compilers i used already completed c++20 features.

c++ variable visibility

PLEASE READ THE SECOND EDIT FIRST.
I am looking for books or websites that explain in detailed the c/c++ memory management models. One of the things I am trying to understand is:
namespace A {
SomeClass A;
}
vs
namespace A {
static SomeClass A;
}
vs
SomeClass A;
vs
static SomeClass A;
Thank you very much.
EDIT:
Sorry for the confusion, I mixed the concepts together, and asked the wrong questions.
Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name.
You use keyword using to introduce a name from a namespace into the current declarative region.
For example:
without using namespace you will write:
#include
int main () {
std::cout << "Hello world!\n";
return 0;
}
However you can also write:
#include
using namespace std;
int main () {
cout << "Hello world!\n";
return 0;
}
This allows you not to append napespace identifier before every
In C++ static class has no meaning unlike other OOP languages. You can have static data members methods.
Instead you can create:
1.A static method in class
class SomeClass
{
public: static void myMethod(int x..)
{
}
}
2.Create a free function in namespace
namespace A
{
void myMethod(int x..)
{
}
}
Latter is better suited when you do not need an object. No class no object...
In both cases enclosing a class within namespace allows you to to group entities under a common name.
First, namespaces are only known until compilation, after that they're non-existant. That said, your first half is no different from your second half in the final program, at least as far as I know. Correct me if I'm wrong please.
Then, if both static SomeClass A and SomeClass A are at global scope (file level), then they're the same too.
Next, if both declarations are inside of a class, struct or function, then the static version will be put into the data segment of the executable too, while the non-static variant will be a normal stack variable.
Again, please, correct me if I'm wrong, but that's it as far as I know it.

C++ privately constructed class

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.

Is it possible to treat a template instance as a namespace?

Suppose I have
template< unsigned int num >
class SomeFunctionality
{
static unsigned int DoSomething()
{
//...
}
static void DoSomethingElse()
{
}
};
typedef SomeFunctionality<6> SomeFunctionalityFor6;
Semantically, "SomeFunctionalityFor6" is essentially a namespace specific to the template argument, 6. So in the code using this instance of the template instead of doing
int main()
{
SomeFunctionalityFor6::DoSomething();
}
I'd rather have the ability to use a "using" statement ala a real namespace
int main()
{
using SomeFunctionalityFor6;
DoSomething();
}
This, as I would suspect doesn't work. Visual studio complains that it wants a namespace defined by the "namespace" keyword following any using statement.
Is there anyway to do what I'm trying to do? Mainly I just don't want to fully qualify the namespace everytime I call the static methods. I know its mostly just syntactic sugar, but in my opinion it can make code much more readable. I'm wondering if there's even ways to templatize a namespace directly instead of having to use the "class" keyword.
You can't do that. Neither templatized namespace, nor using class_name.
The only places in the code that can use static functions from a class without qualification are derived classes.
In your case, I would use a typedef for some short name, like
int main()
{
typedef SomeFunctionalityFor6 SF6;
SF6::DoSomething();
}
Or you could just create a local object...
int main()
{
SomeFunctionalityFor6 SF6;
SF6.DoSomething();
}
You could replace/change the SF6 object at will.