When binding a C++ structure to Emscripten like so:
struct Foo {
int n;
};
#include <emscripten/bind.h>
using namespace emscripten;
EMSCRIPTEN_BINDINGS(myproject) {
class_<Foo>("Foo")
.constructor<>()
.property("n", &Foo::n);
}
Does the constructor<>() declaration guarantee that the n member will be initialized to zero when constructed with new in JavaScript? I would assume it calls C++'s Foo() or new Foo(), meaning yes, but I can't find any source confirming this.
Related
I am new to cpp, looking at an existing project.
There are several places in the project where an object is defined in a namespace in some header file and then declared in the same namespace and used in other declarations in some other header file. Example:
MyStruct.hpp:
namespace A { struct MyStruct { int i; }; }
MyClass.hpp:
namespace A { struct MyStruct; }
namespace B {
class MyClass {
private:
void foo(A::MyStruct& s);
};
}
MyClass.cpp:
#include "MyClass.hpp"
#include "MyStruct.hpp"
namespace B {
class MyClass {
void foo(A::MyStruct& s) { /* ... */ }
};
}
I might have expected there to be an #include "MyStruct.hpp" in MyClass.hpp, but that is not the case. I guess when the two header files are isolated there is not yet any relationship between the MyStruct objects in that case. Why does this not create some conflict though when the two headers are loaded together in the implementation file? I cannot, for instance, write int j; int j = 0;. Does the order of the #includes matter? And what might be the motivation for doing this?
What you are seeing is a forward declaration being used.
Since foo() takes a MyStruct by reference, MyClass.hpp doesn't need to know the full declaration of MyStruct in order to declare foo(), it only needs to know that MyStruct exists somewhere. The linker will match them up later.
MyClass.cpp, on the other hand, needs to know the full declaration of MyStruct in order for foo()'s implementation to access the contents of its s parameter. So MyStruct.hpp is used there instead.
This also means that if the contents of MyStruct.hpp are ever modified, any source files using MyClass.hpp don't have to be recompiled since the forward declaration of MyStruct won't change (unless the namespace is changed, that is). Only files that are using MyStruct.hpp will need recompiling, like MyClass.cpp.
MyClass.hpp contains a forward declaration of MyStruct; it’s just telling the compiler that a type named struct MyStruct exists, but not providing any details about what’s in the struct. That’s enough for things like const MyStruct & to compile without syntax errors, but not enough to actually do anything with the struct (since its size and contents are still unknown to the compiler)
As for why someone would do that instead of putting in an #include; it’s a little bit faster to compile, but the main reason would be to avoid cyclic dependencies (eg if MyStruct.h needs to reference MyClass but MyClass.h also needs to reference MyStruct, that would be difficult to achieve using only #include directives)
When invoking a standard method, for example, std::sort(), we just need a namespace and can further simply by using namespace std;
How can I do this with a user-defined class or is it impossible. (No pre-processor macro solution please). I tried using this:
#include <iostream>
using namespace std;
namespace std
{
class A
{
public:
static void foo()
{
std::cout << "foo";
}
};
}
int main ()
{
//foo(); does not work
A::foo(); //Only this works
}
Replacing std by any other namespaces also doesn't work.
When invoking a standard method, for example, std::sort(), we just need a namespace and can further simply by using namespace std; How can I do this with a user-defined class [...]
std::sort is a template not a function, but otherwise it is not different from code you can write yourself:
namespace foo {
void bar() {}
}
using namespace foo;
int main() {
bar(); // ok
}
This works for namespaces but not for members of classes (there is using for members of classes to bring something from a base class scope into the derived class scope, but thats a different topic and beyond the scope of the question (no pun intended), it is not what you are asking for here).
In your example there is no reason why foo should be a member of A, hence you should make it a free function (as above). Supposed you didn't write A but you still need to call it without qualifiying the class name you can wrap it in a free function.
Also note that you are not allowed to add something to namespace std. If you do, your code has undefined behavior.
And finally, note that there are good reasons to discourge usage of using some_namespace; altogether. Consider this:
namespace foo1 {
void bar(){}
}
namespace foo2 {
void bar(){}
}
// lots of other code
using namespace foo1;
// lots of other code
int main() {
foo1::bar(); // this is bar from foo1
foo2::bar(); // this is bar from foo2
bar(); // to know which bar this is you have to
// look for any using directive, ie
// it makes your code much harder to read
}
Code is written once but read many times. The 6 extra characters to type pay off in more clear code. See also:
Why is “using namespace std;” considered bad practice?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Code convert from C++ to C
Converting a C++ class to a C struct (and beyond)
I used to be a C++ programmer, but now I need to write a program in C.
e.g. in C++
Main.cpp
=====================
int main
{
ns::Sum sum(1, 2);
}
Sum.h
=====================
namespace ns
{
class Sum
{
public:
Sum(int a, int b);
private:
void AddThemUp();
int a;
int b;
}
}
Sum.cpp
======================
namespace ns
{
Sum::Sum(int a, int b)
{
this->a = a;
this->b = b;
AddThemUp();
}
void Sum::AddThemUp()
{
a + b;//stupid for returning nothing, just for instance
}
}
That's in C++
I don't know how to put above in C. because there is no class there.
if I declare data member a & b in header file, they will become global variables.
I don't like global variables. and is there namespace in C?
who can help? thank you
Here is a simple conversion from C++ to C. This method allows for stack objects, like how you use ns::Sum. As a note, you should also have a release function that cleans up any memory allocated by the structure.
// Main.c
// =====================
// Construction
ns_Sum sum;
ns_SumInitWithAAndB(&sum, 1, 2);
// Sum.h
// =====================
// All member variables are contained within a struct
typedef struct ns_Sum_
{
int a;
int b;
} ns_Sum;
// Public Methods
void ns_SumInitWithAAndB(ns_Sum *sum, int a, int b);
// Sum.c
// ======================
// Private Methods can be declared as static functions within the .c file
static void ns_SumAddThemUp(ns_Sum *sum);
void ns_SumInitWithAAndB(ns_Sum *sum, int a, int b)
{
sum->a = a;
sum->b = b;
ns_SumAddThemUp(sum);
}
void ns_SumAddThemUp(ns_Sum *sum)
{
a + b; //stupid for returning nothing, just for instance
}
No, that is one of the limitations of C, you do not have separate namespaces built into the language. This is usually done by adding prefixes to names. As for global variables, you can use the extern storage specifier to declare but not define them.
Header:
#pragma once
extern int ns_foo;
Souce:
#include "header.h"
int ns_foo = 0;
Others already have pointed out how to use a name prefix to simulate a namespace.
But there seem to be another misunderstanding in your question. Only static data members translate to "global" variables in C. Other "normal" data members are distinct for each instance of your struct.
public static members are global variables, so you can not expect this to work better int C. private static members can be replaced by static variables that are only declared inside your .c file in which you define your functions. The only restriction is then that these are not visible for inline functions, as they would be for inline member functions in C++.
Another thing that should perhaps be added is that you could try to start to think in C when you are doing such a project. Modern C has some tools that don't exist in C++, the intersection of C and C++ is quite a restricted language. Such tools are, e.g:
designated initializers that may replace constructors with an empty function body
compound literals that provide temporary variables in expressions
pointers to VLA (variable length arrays) that can provide you with convenient interfaces for vector and matrix functions
The conventional approach to use certain features which C++ gives you in C++ has to do with a lot of manual work:
Instead of using namespace, you'd use prefixes for your structs and functions, e.g., struct ns_Sum and void ns_Sum_AddThemUp().
C doesn't have member functions. So, instead of calling function on an object, you'd rather pass the object as a first parameter, e.g., void ns_Sum_SumThemUp(ns_Sum* object).
The way to make members private is to only declare the struct in the header and define it in the source. This goes together with suitable create and destroy function:
That is the declarations in a C header could look something like this:
typedef struct ns_Sum ns_Sum;
ns_Sum* ns_Sum_Create();
void ns_Sum_Destroy(ns_Sum*);
void ns_Sum_AddThemUp(ns_Sum const*);
For simple structures using a mapping like this works reasonable well. It becomes a Royal pain in the some-body-part-goes-here to also implement polymorphic dispatch or to deal with the moral equivalent of templates. My personal view of using C++ in C is to use C++ but I realize that this preference isn't shared with everybody...
I am using an API that has a lot of functions in a class named TCODConsole as static functions. Now I thought that it was in a namespace, so I wrote: using namespace TCODConsole;. Then I found out that TCODConsole ain't a namespace, but a class.
Is there a way to import those functions in a similar way as you would use using namespace?
No, there is no shortcut way to call myStaticFun() instead of MyClass::myStaticFun(). You cannot do that with class. It's a class, not a namespace. But you can write something like a wrapper. That is you will add functions with same name and call the static methods from that functions. Something like this:
class MyClass {
static void fun();
};
void fun() {
MyClass::fun();
}
// call it
fun();
Not a very good way. Personally I think it is better to stick with the class instead of doing this.
Though I may misunderstand the question,
if shortening the qualification is the objective,
does typedefing like the following meet the purpose?
struct TCODConsole {
static void f();
static void g();
};
int main() {
typedef TCODConsole T;
T::f();
T::g();
}
Alternatively, if the class TCODConsole can be instantiated,
since static member function can be called with the same form as
non-static member function, the following code might meet the purpose:
int main() {
TCODConsole t;
t.f();
t.g();
}
I can't think of a clean way to do it, but I can think of a kinda ugly hack that will work, as long as the code using it is part of a class (and if TCODConsole really contains only static member functions). Let's say you are bar(), a member function of the class Foo, and you want to call a function baz() which is a static member of TCODConsole without fully-qualifying it. What you can do is to privately derive Foo from TCODConsole:
class Foo : private TCODConsole
{
void bar()
{
baz();
}
};
Yeah, that's ugly. :(
If you want to use Boost.PP (the Boost Preprocessor macro library - you don't need to compile or include anything else from Boost to use it), you can probably make a less ugly but quite a bit more convoluted macro which will "import" these functions for you, by wrapping them with inline functions inside another namespace (which you can then import at will). It would still require you to explicitly specify the name each of the functions you want to "import", so your code (minus the macro) will look something like this:
namespace TCODStatic
{
IMPORT_FROM_TCOD(foo)
IMPORT_FROM_TCOD(bar)
IMPORT_FROM_TCOD(baz)
IMPORT_FROM_TCOD(spaz)
}
and then you'll be able to write using namespace TCODStatic; anywhere you want.
Short answer: not without using macros. There is no mechanism in the C++ language proper to do something like this:
class A
{
public:
static void foo();
};
// ...
using A;
foo();
You could use a macro to build these expressions for you:
#define FOO() (A::foo())
FOO();
I would discourage this however, because it can become a maintennence nightmare is you make extensive use of such macros. You end up with code like this:
FOO();
BAR();
SUPERGIZMO(a, b, c);
...where none of these things are defined as first-class names anywhere in the program. You've lost all type checking, the code uses a "secret language" that only you know, and it becomes difficult to debug, extend and fix.
EDIT:
You could write a kind of bridge. Like this:
class FooBar
{
public:
static void gizmo();
};
namespace Foo
{
void gizmo() { FooBar::gizmo(); };
};
using namespace Foo;
gizmo();
I am confused what to do when having nested namespaces and declarations of objects.
I am porting some code that links against a static library that has a few namespaces.
Example of what I am talking about:
namespace ABC {
namespace XYZ {
//STUFF
}
}
In code what do I do to declare an object that is in namespace XYZ?
if I try:
XYZ::ClassA myobject;
or:
ABC::XYZ::ClassA myobject;
or:
ABC::ClassA myobject;
I get
does not name a type
errors, even though ClassA definitely exists.
What is proper here?
It depends on the namespace you already are:
If you're in no namespace or another, unrelated namespace, then you have to specify to whole path ABC::XYZ::ClassA.
If you're in ABC you can skip the ABC and just write XYZ::ClassA.
Also, worth mentioning that if you want to refer to a function which is not in a namespace (or the "root" namespace), you can prefix it by :::
Example:
int foo() { return 1; }
namespace ABC
{
double foo() { return 2.0; }
void bar()
{
foo(); //calls the double version
::foo(); //calls the int version
}
}
If myobject is declared in that namespace and you want to declare it again (for defining it), you do it by prefixing its name, not its type.
ClassA ABC::XYZ::myobject;
If its type is declared in that namespace too, you also need to prefix the name of the type
ABC::XYZ::ClassA ABC::XYZ::myobject;
It's rarely needed to redeclare an object like that. Often the first declaration of an object is also its definition. If you want to first declare the object, you have to do it in that namespace. The following declares and defines "myobject"
namespace ABC {
namespace XYZ {
ClassA myobject;
}
}
If you have defined in object like this, you refer to it by saying ABC::XYZ. You don't have to "declare" that object somehow in order to use it locally
void f() {
ABC::XYZ::myobject = someValue;
// you *can* however use a using-declaration
using ABC::XYZ::myobject;
myobject = someValue;
}