I am baffled by a static method whose definition apparently lives in one class, but whose declaration is shared between several classes in the same file. Can it be shared between files somehow?
The Details
I'm trying to divide a .mm file into several files (one per class). All of the source code is from Pete Goodliffe's CoreMIDI Example.
I took the PGMidi class from here and busted it up into separate interfaces and classes. Everything compiles perfectly except for one method marked static, which needs to be in two places at once (it's "used but never defined" in PGMidi). The method is "used" in this line outside of any class implementation:
static void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon);
which is apparently shared by all classes in the same file (what?). It's mentioned in two classes.
1) In PGMidi, where it's used (perhaps pointing to PGMidiSource
s = MIDIInputPortCreate(client, (CFStringRef)#"MidiMonitor Input Port", PGMIDIReadProc, self, &inputPort);
2) In PGMidiSource, where the method body is defined
static
void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon)
{
PGMidiSource *self = (PGMidiSource*)srcConnRefCon;
[self midiRead:pktlist];
}
The problem is that the self referred to in the method body makes no sense in PGMidi (no midiRead method)...
What is this static method? How I can get it to work between two files?
The static function is just a normal C function. The 'static' means it can only be accessed from within the same file. So you need to either:
Redefined it for every file you want use it from, typically by putting the entire static function definition in a header and include the header in every file you want to use it, or
Make it a non-static function and put the function prototype in a header, then include the header in every file you want to use it from.
On a function, the static keyword roughly means "only visible and usable from within this file". Since it was defined in PGMidiSource.mm, you cannot call it from PGMidi.mm. Luckily, this is fairly easy to fix.
Declare the function prototype in PGMidiSource.h, like this:
void PGMIDIReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon);
Remove the static keyword in PGMidiSource.mm, since it needs to be usable from outside that file.
Note that this is not a "method"; it is a C function. As such, it belongs to no class, is not tied to any instance, has no access to any instance variables, etc. Any context that it needs must be passed in as a parameter. Hence, while this function uses a variable called "self", it's actually just a local alias for one of the parameters that was passed in.
The reason that it looks like that "method" is shared between multiple classes is because it's not technically a method. Instead, that's a C function. You can add C to Objective C in that manner, and that particular function can be invoked from multiple files, though it's a good practice to provide a "prototype" in a header file for the files that don't have the actual function implemented within them. (Or it was the last time I wrote in C. It's been a while.)
If you don't provide the prototype in the other files, C will let you go merrily on your way (though the compiler will probably say it doesn't know anything about that function in a warning.) But the linker will resolve it, and assuming it's coded correctly, it should work.
Related
I've got a C++/CLI layer that I've been using successfully for a long time. But I just discovered something that makes me think I need to relearn some stuff.
When my C++/CLI functions receive an instance of any managed class, they use the "hat" operator ('^') and when they receive an instance of a managed struct, they do not. I thought this was how I was supposed to write it.
To illustrate as blandly as I can
using Point = System::Windows::Point;
public ref class CppCliClass
{
String^ ReturnText(String^ text) { return text; } // Hat operator for class
Point ReturnStruct(Point pt) { return pt; } // No hat operator for struct
};
I thought this was required. It certainly works. But just today I discovered that CancellationToken is a struct, not a class. My code accepts it with a hat. I thought it was a class when I wrote it. And this code works just fine. My cancellations are honored in the C++/CLI layer.
void DoSomethingWithCancellation(CancellationToken^ token)
{
// Code that uses the token. It works just fine
}
So apparently I can choose either method.
But then what is the difference between passing in a struct by value (as I've done with every other struct type I use, like Point) and by reference (as I'm doing with CancellationToken?). Is there a difference?
^ for reference types and without for value types matches C#, but C++/CLI does give you more flexibility:
Reference type without ^ is called "stack semantics" and automatically tries to call IDisposable::Dispose on the object at the end of the variable's lifetime. It's like a C# using block, except more user-friendly. In particular:
The syntax can be used whether the type implements IDisposable or not. In C#, you can only write a using block if the type can be proved, at compile time, to implement IDisposable. C++/CLI scoped resource management works fine in generic and polymorphic cases, where some of the objects do and some do not implement IDisposable.
The syntax can be used for class members, and automatically implements IDisposable on the containing class. C# using blocks only work on local scopes.
Value types used with ^ are boxed, but with the exact type tracked statically. You'll get errors if a boxed value of a different type is passed in.
I've always known what static methods are by definition, but I've always avoided using them at school because I was afraid of what I didn't know.
I already understand that you can use it as a counter throughout your entire project.
Now that I am interning I want to know when exactly static methods are used. From my observation so far, static classes/methods are used when it contains a lot of functions that will be used in many different classes and itself doesn't contain too many critical local variables within the class where it is not necessary to create an instant of it.
So as an example, you can have a static class called Zip that zips and unzips files and provide it to many different classes for them to do whatever with it.
Am I right? Do I have the right idea? I'm pretty sure there are many ways to use it.
Static functions are helpful as they do not rely on an instantiated member of whatever class they are attached to.
Static functions can provide functionality related to an a particular class without requiring the programmer to first create an instance of that class.
See this comparison:
class Numbers
{
public int Add(int x, int y)
{
return x + y;
}
public static int AddNumbers(int x, int y)
{
return x + y;
}
}
class Main
{
//in this first case, we use the non-static version of the Add function
int z1 = (new Numbers()).Add(2, 4);
//in the second case, we use the static one
int z2 = Numbers.AddNumbers(3, 5);
}
Technically, answers above are correct.
But the examples are not correct from the OOP point of view.
For example you have a class like this:
class Zip
{
public static function zipFile($fileName)
{
//
}
public static function unzipFile($fileName)
{
//
}
}
The truth is that there is nothing object-oriented here. You just defined two functions which you need to call using the fancy syntax like Zip::zipFile($myFile) instead of just zipFile($myFile).
You don't create any objects here and the Zip class is only used as a namespace.
So in this case it is better to just define these functions outside of class, as regular functions. There are namespaces in php since version 5.3, you can use them if you want to group your functions.
With the OOP approach, your class would look like this:
class ZipArchive
{
private $_archiveFileName;
private $_files;
public function __construct($archiveFileName) {
$this->_archiveFileName = $archiveFileName;
$this->_files = [];
}
public function add($fileName)
{
$this->_files[] = $fileName;
return $this; // allows to chain calls
}
public function zip()
{
// zip the files into archive specified
// by $_archiveFileName
}
}
And then you can use it like this:
$archive = new ZipArchive('path/to/archive.zip');
$archive->add('file1')->add('file2')->zip();
What is more important, you can now use the zip functionality in an OOP way.
For example, you can have a base class Archive and sub-classes like ZipArchive, TarGzArchive, etc.
Now, you can create an instance of the specific sub-class and pass it to other code which will not even know if files are going to be zip-ped or tag.gz-ipped. For example:
if ($config['archive_type'] === 'targz') {
// use tar.gz if specified
$archive = new TarGzArchive($path);
} else {
// use zip by default
$archive = new ZipArchive($path);
}
$backup = new Backup($archive /*, other params*/);
$backup->run();
Now the $backup object will use the specified archive type. Internally it doesn't know and doesn't care how exactly files will be archived.
You can even have a CopyArchive class which will simply copy files to another location.
It is easy to do it this way because your archive support is written in OOP way. You have small object responsible for specific things, you create and combine them and get the result you want.
And if you just have a bunch of static methods instead of real class, you will be forced to write the procedural-style code.
So I would not recommend to use static methods to implement actual features of your application.
Static methods may be helpful to support logging, debugging, testing and similar things. Like if you want to count number of objects created, you can use class-level static counter, increment it in the constructor and you can have a static method which reads the counter and prints it or writes to the log file.
Yes, static classes are used for problems that require stateless computation. Such as adding two numbers. Zipping a file. Etc.
If your class requires state, where you need to store connections or other longer living entities, then you wouldn't use static.
AFAIK. Static methods does not depends on a class instance. Just that.
As an example:
If you have an single thread program that will have only ONE database connection and will do several queries against the database it will be better to implement it as a static class (note that I specified that you will not connect, ever to several databases or have several threads).
So you will not need to create several connection objects, because you already know that you will only use one. And you will not need to create several objects. Singletons in this scenario are, also, an option.
There are other examples.
If you create an class to convert values.
class Convert{
static std::string fromIntToString(int value);
}
This way you will not need to create the class convert every time you need to convert from integer to an string.
std::string value = Convert::fromIntToString(10).
If you haven't done that you would need to instantiate this class several times through your program.
I know that you can find several other examples. It is up to you and your scenario to decide when you are going to do that.
This question already has answers here:
Are static local variables bad practice?
(2 answers)
Closed 8 years ago.
Consider the following functionally two code snippets in a single-threaded environment. Assuming there are no other methods in Foo I believe these are functionally identical.
Class Foo
Private _Bar As Bar
Public ReadOnly Property GetBar As Bar
Get
If IsNothing(_Bar) Then
_Bar = New Bar
End If
Return _Bar
End Get
End Property
End Class
And
Class Foo
Public ReadOnly Property GetBar2 As Bar
Get
Static _Bar As New Bar
Return _Bar
End Get
End Property
End Class
Today I was challenged on code following the 2nd method because "the New will be called each time". I already know that is false, but the primary objection was with regards to the use of Static. I found several references to Static variables indicating that they may be dangerous, but they were all talking about Java. However, I was not able to find any good explanations as to why.
How are these two methods different? Is the 2nd method dangerous? If so, why?
Static in VB.Net is not that same as static in Java, C#, C, or C++. VB.Net's analog to that construct is Shared. The documentation on the Static keyword is here:
http://msdn.microsoft.com/en-us/library/z2cty7t8.aspx
In particular, I'd like to point out this snippet:
Behavior
When you declare a static variable in a Shared procedure, only one copy of the static variable is available for the whole application. You call a Shared procedure by using the class name, not a variable that points to an instance of the class.
When you declare a static variable in a procedure that isn't Shared, only one copy of the variable is available for each instance of the class. You call a non-shared procedure by using a variable that points to a specific instance of the class.
It's likely the objection comes from believing that Static always behaves like the first paragraph, even in instance methods, when we can see here that it's clearly documented that this is not the case.
Instead, Static allows you to declare a variable whose lifetime-scope is that of the class instance, but whose access-scope is limited to a single method. It's a way to narrow the potential scope of a variable, and therefore is a good thing. Additionally, variables declared as Static are rewritten by the compiler to be protected via the Monitor class (at least for the Shared version), giving them a measure of thread-safety. In other words, a variable declared as Static is more likely to have any needed locking done verses a similar class-scoped variable.
In this particular case, though, I fail to see the point. You don't really gain anything beyond an auto-implemented property like this:
Public ReadOnly Property GetBar2 As New Bar()
This probably is confusing the VB.net concepts of Static and Shared because some languages use the keyword Static to mean what VB uses Shared for: a variable/field/property/method that is shared or common to all instances of a class.
But Static doesn't mean that in VB. Instead it means a routine-local variable that persists beyond the invocation of the routine (i.e., its lifetime is object-scoped rather than routine invocation-scoped).
REF: http://msdn.microsoft.com/en-us/library/z2cty7t8.aspx
So in VB, Static means "routine-scoped visibility, object-scoped lifetime".
Whereas Shared means "class-scoped visibilty, class/program-scoped lifetime".
I would avoid the second approach if for no other reason than the fact that C and C# have a static keyword whose meaning is totally different from that of the VB.NET Static keyword. I generally dislike language features which look like features of other languages but aren't. If it's necessary to use a language feature despite its unfortunate resemblance to the other language's feature, I'll use it, but the VB.NET static keyword doesn't really add much here. Effectively, it asks the compiler to make the variable Private field, give it an arbitrary name which differs from that of any other field, and replace all references to the variable's given name within the method with references to the invented name.
Conceptually, use of such "localized" fields may be regarded as dubious because while one may expect that a field will only need to be used within one method, that may turn out not to be true. I wouldn't worry too much about that issue in vb.net, however, because a Static variable may easily be turned into an ordinary private field if the need arises. If when that need does arise a field exists with the same name, one may easily rename the Static variable before moving it.
I have two c++/cli dlls (i.e. compiled with /clr) where A.dll references B.dll. In assembly B, I have a method, GetMgdClassB, I'd like to call from assembly A. Here is the code in assembly B (B.cpp):
namespace B
{
public class NativeClassB
{
public:
NativeClassB();
// ...
};
public ref class MgdClassB
{
public:
static MgdClassB ^ GetMgdClassB(const std::vector<NativeClassB *> & vecNativeBs)
{
// ...
vecNativeBs;
return gcnew MgdClassB();
}
};
}
Notice that the method GetMgdClassB takes a std::vector. In assembly A, I attempt to call this method with the following code (A.cpp):
namespace B
{
class NativeClassB;
}
#pragma make_public(std::vector<B::NativeClassB *>)
namespace A
{
void Foo()
{
std::vector<B::NativeClassB *> vecNativeBs;
B::MgdClassB::GetMgdClassB(vecNativeBs);
}
}
When I compile A.cpp, I get the following error:
error C2158: 'std::vector<_Ty>' : #pragma make_public directive is currently supported for native non-template types only
the reason I wanted to add this pragma is because native types are private to the assembly by default. If I remove the pragma I get the following error (as expected):
error C3767: 'B::MgdClassB::GetMgdClassB': candidate function(s) not accessible
since the template instantiation type std::vector<B::NativeClassB *> is private to the assembly.
Attempted Solutions
1. Use void *, break type safety:
Change the method, GetMgdClassB to take a void * and pass the address of the std::vector<NativeClassB *> to the method. In GetMgdClassB. I can then static_cast the passed in void * to std::vector<NativeClassB *> *. This, of course, works, but breaks type safety.
2. Create a Managed wrapper for NativeClassB, pass a managed container
Create a managed class, say ref class NativeClassBWrapper who's sole purpose is to hang on to a reference to the native NativeClassB. Change GetMgdClassB to take a managed container of NativeClassBWrappers (e.g. List<NativeClassBWrapper ^> ^). This has the downside of having to create and populate a new managed container prior to calling GetMgdClassB, and then within managed class B, I have to repackage it into the the native container std::vector<NativeClassB *> (since the code in B deals with this type.
Currently, I'm leaning toward going with Solution #1, since (a) it doesn't introduce any performance concerns and (b) I'll only be doing this in a few cases. I don't like losing the type safety, but it seems justifiable given the current deficiency in the compiler's ability to make native template instantiation types visible.
Question:
Are there better work arounds?
Related Question:
C++ CLI error C3767: candidate function(s) not accessible
I'm not aware of any way to export that type. If you have to have that function signature, I would lean in the direction of using a mix of managed and native exports (managed functions using native types can't be consumed by other languages anyway), and maybe use delay loading when calling the native exports so you have a chance to trap errors finding the assembly in the usual .NET way.
But your particular function may be problematic since it uses both managed types and complex native types in the signature.
In general, the best practice is to not pass native C++ classes across DLL boundaries at all, since this sets you up for One Definition Rule violations.
For this particular situation, my suggestion is to make an wrapper that implements ICollection. That cures the problem just like your solution #2, without ever having to actually copy all the elements into a new data structure.
I received a solution from Mike Danes on another forum:
http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/b43cca63-b0bf-451e-b8fe-74e9c618b8c4/
Basically, the solution is to create a native wrapper (call it VectorOfNativeB) in assembly B that holds on to a pointer or reference to the std::vector. Export VectorOfNativeB and make it publicly visible. Change method GetMgdClassB to take a pointer or reference VectorOfNativeB.
[posted this here for future reference and to see if anyone here has any comments about this solution].
I'm often running into the same trail of thought when I'm creating private methods, which application is to modify (usually initialize) an existing variable in scope of the class.
I can't decide which of the following two methods I prefer.
Lets say we have a class Test with a field variable x. Let it be an integer. How do you usually modify / initialize x ?
a) Modifying the field directly
private void initX(){
// Do something to determine x. Here its very simple.
x = 60;
}
b) Using a return value
private int initX(){
// Do something to determine x. Here its very simple.
return 60;
}
And in the constructor:
public Test(){
// a)
initX();
// b)
x = initX();
}
I like that its clear in b) which variable we are dealing with. But on the other hand, a) seems sufficient most of the time - the function name implies perfectly well what we are doing!
Which one do you prefer and why?
Thank for your answers guys! I'll make this a community wiki as I realize that there is no correct answer to this.
I usually prefer b), only I pick a different name, like computeX() in this case. A few reasons for why:
if I declare computeX() as protected, there is a simple way for a subclass to influent how it works, yet x itself can remain a private field;
I like to declare fields final if that's what they are; in this case a) is not an option since initialization has to happen in compiler (this is Java-specific, but your examples all look Java as well).
That said, I don't have a strong preference between the two methods. For instance, if I need to initialize several related fields at once, I will usually pick option a). That, though, only if I cannot or don't want for some reason, to initialize directly in constructor.
For initialization I prefer constructor initialization if it's possible,
public Test():x(val){...}, or write initialization code in the constructor body. Constructor is the best place to initialize all the fields (actually, it is the purpose of constructor). I'd use private initX() approach only if initialization code for X is too long (just for readability) and call this function from constructor. private int initX() in my opinion has nothing to do with initialization(unless you implement lazy initialization,but in this case it should return &int or const &int) , it is an accessor.
I would prefer option b), because you can make it a const function in languages that support it.
With option a), there is a temptation for new, lazy or just time-stressed developers to start adding little extra tasks into the initX method, instead of creating a new one.
Also, in b), you can remove initX() from the class definition, so consumers of the object don't even have to know it's there. For example, in C++.
In the header:
class Test {
private: int X;
public: Test();
...
}
In the CPP file:
static int initX() { return 60; }
Test::Test() {
X = initX();
}
Removing the init functions from the header file simplifies the class for the people that have to use it.
Neither?
I prefer to initialize in the constructor and only extract out an initialization method if I need a lot of fields initialized and/or need the ability to re-initialize at another point in the life time of an instance (without going through a destruct/construct).
More importantly, what does 60 mean?
If it is a meaningful value, make it a const with a meaningful name: NUMBER_OF_XXXXX, MINUTES_PER_HOUR, FIVE_DOZEN_APPLES, SPEED_LIMIT, ... regardless of how and where you subsequently use it (constructor, init method or getter function).
Making it a named constant makes the value re-useable in and of itself. And using a const is much more "findable", especially for more ubiquitous values (like 1 or -1) then using the actual value.
Only when you want to tie this const value to a specific class would it make sense to me to create a class const or var, or - it the language does not support those - a getter class function.
Another reason to make it a (virtual) getter function would be if descendant classes need the ability to start with a different initial value.
Edit (in response to comments):
For initializations that involve complex calculations I would also extract out a method to do the calculation. The choice of making that method a procedure that directly modifies the field value (a) or a function that returns the value it should be given (b), would be driven by the question whether or not the calculation would be needed at other times than "just the constructor".
If only needed at initialization in the constructor, I would prefer method (a).
If the calculation needs to be done at other times as well, I would opt for method (b) as it also makes it possible to assign the outcome to some other field or local variable and so can be used by descendants or other users of the class without affecting the inner state of the instance.
Actually only a) method behaves as expected (by analyzing method name). Method b) should be named 'return60' in your example or 'getXValue' in some more complicated one.
Both options are correct in my opinion. It all depeneds what was your intention when certain design was choosen. If your method has to do initialization only I would prefer a) beacuse it is simplier. In case x value is also used for something else somewhere in logic using b) option might lead to more consistent code.
You should also always write method names clearly and make those names corresponding with actual logic. (in this case method b) has confusing name).
#Frederik, if you use option b) and you have a LOT of field variables, the constructor will become a quite unwieldy block of code. Sometimes you just can't help but have lots and lots of member variables in a class (example: it's a domain object and it's data comes straight from a very wide table in the database). The most pragmatic approach would be to modularize the code as you need to.