I'm relative new to C++ and my background is in Java. I have to port some code from Java to C++ and some doubts came up relative to the Object Java's class. So, if I want to port this:
void setInputParameter(String name, Object object) { ..... }
I believe I should use void* type or templates right? I don't know what's the "standard" procedure to accomplish it.
Thanks
It depends what you want to do with object.
If you use a template, then any methods you call on object will be bound at compile time to objects type. This is type safe, and preferable, as any invalid use of the object will be flagged as compiler errors.
You could also pass a void * and cast it to the desired type, assuming you have some way of knowing what it should be. This is more dangerous and more susceptible to bugs in your code. You can make it a little safer by using dynamic_cast<> to enable run-time type checking.
If you want to accept a pointer to an arbitrary object, then you would want the type to be void *. However, that would be the end of the function, you can't do anything with a void * except store it's value or cast it to a pointer to some known object. If you're going to cast it anyway, then you probably know what the object is, so you don't need the void *.
C++ just doesn't have the same kinds of introspection abilities that Java has. In other words, there's not a convenient way to say something like myObject.getClass().getName(). The closest thing that I'm aware of is runtime type information (RTTI), which you can see in action here.
The other alternative is to create your own root class, and write your own introspection methods (a lot of C++ frameworks do this).
Related
I'm currently working on a component-based architecture management system in java. My current implementation of the retrieval of a component attached to an object works like this:
// ...
private final HashMap<Class<? extends EntityComponent>, EntityComponent> components;
// ...
public <T extends EntityComponent> T getComponent(Class<T> component)
{
// ... some sanity checks
if (!this.hasComponent(component))
{
// ... some exception handling stuff
}
return component.cast(this.components.get(component));
}
// ...
Now, this works fine, but it somewhat bugs me to have to write
object.getComponent(SomeComponent.class)
everytime I need to access a component.
Would it be possible to utilize generics in a way to shift the syntax to something more along the lines of
object.getComponent<SomeComponent>()
, utilizing the diamond operator to specify the class, instead of passing the class of the component as a parameter to the method?
I know it's not really a big thing, but making the syntax of often used code as pretty / compact as possible goes a long way I guess.
Unfortunately not, since type-parameters are "erased" in Java. That means that they are only available at compile-time (where the compiler is using them to type-check the code), but not at run-time.
So when your code is running, the <SomeComponent> type-parameter no longer exists, and your code therefore can't do any operations (if/else, etc) based on its value.
In other words:
At compile time, your method call looks like this: object.getComponent<SomeComponent>()
But after compilation your method call just looks like this object.getComponent(). There is no type-parameter any more.
So, yes, unfortunately you still need to pass a Class object along, or something similar (see "Super Type Tokens" for example), if you need to do something that depends on the type parameter at run-time.
The reason the Class workaround works is that it loosely speaking represents the type-parameter, since the type-checker makes sure that its instance fits with the type-parameter, but is an object and thus available at run-time too - unlike the type-parameter.
Note: The Class-trick doesn't work for type-parameters within type-parameters, such as Class<List<Something>>, since at run-time List<Something> and List<OtherThing> is the same class, namely List. So you can't make a Class token to differentiate between those two types. As far as i remember "Super Type Tokens" can be used instead to fix this (they exploit the fact that there is an exception to erasure: For subclasses of generic classes, the type-parameters used when "extending" the superclass are actually available at run-time through reflection. (there are also more exceptions: https://stackoverflow.com/a/2320725/1743225)).
(Related google terms: "Erasure", "Reification", "Reified generics")
I want to know what the modern C++11 equivalent of Java's instanceof. I have seen this SO post but it is quite old and was wondering if there's a more modern, better solution in C++11?
I was hoping there's a possibility of using a switch construct without having to resort to a manual enum class.
class A {
};
class B : public A {
}
class C : public A {
}
on_event(A& obj)
{
switch (obj) {
case A:
case B:
case C:
}
}
My base class does not have any virtual methods or functions. I am representing an expression tree for a parser and the base class is just a polymorphic holder - like an ADT in Haskell/OCaml.
The same answer still applies, and has always been like this in C++:
if (C * p = dynamic_cast<C *>(&obj))
{
// The type of obj is or is derived from C
}
else
{
// obj is not a C
}
This construction requires A to be polymorphic, i.e. to have virtual member functions.
Also note that this behaviour is different from comparing typeid(obj) == typeid(C), since the latter tests for exact type identity, whereas the dynamic cast, as well as Java's instanceof, only test for the target type to be a base class of the type of the most-derived object.
In C++ plain old data (POD) has no runtime type information. The classes described all take exactly 1 byte, and have identical runtime representations in any compiler with the empty base class optimization.
As such what you want cannot be done.
Adding a virtual destructor to the base class adds in RTTI, and dynamic_cast support.
Adding an enum or int field to the base that gets initialized differently for each derived class also works.
Yet another option is to create a template function, and store a pointer to it, like so:
using my_type_id=void(*)();
template<class>void get_my_type_id_helper(){};
template<class T> my_type_id get_my_type_id(){return get_my_type_id_helper<T>;}
and then storing a my_type_id in A initialized appropriately. This is reinventing RTTI, and as you want more features you will approach C++ RTTI overhead.
In C++ you only pay for what you ask for: you can ask for classes without RTTI, which you did, and get it.
RTTI is Run Time Type Information. POD is plain old data, a C++03 term. Many classes are not POD: the easy way is to add a virtual destructor. C++11 has more fine grained standard layout and aggregate terms.
Technically RTTI and POD are not opposites of each other: there are classes with no RTTI that are not POD.
Note that MSVC has options to not generate RTTI and its aggressive Comdat folding can break the manual RTTI I did above, in both cases in violation of the standard.
Maybe you are interested in the answer I've posted inside your mentioned old SO post.
https://stackoverflow.com/a/49296405/1266588
The answer presents an implementation of instanceof without the usage of dynamic_cast based on C++11, template metaprogramming and RTTI. A small performance measurement application demonstrates that it is more efficient than dynamic_cast if you use compiler optimization.
Don't do that. In most cases you should review your design when you ask for instanceof or dynamic_cast.
Why? You are most likely violating Liskov's substitiontin principle.
How about this approach:
class A {
public:
virtual void action();
virtual ~A();
};
class B : public A {
public: void action() override;
};
class C : public A {
public: void action() override;
};
void on_event(A& obj)
{
obj.action();
}
Note that as #Yakk pointed out you need at least one virtual method anyway to get dynamic polymorphism. And there is a rule that says: When you have at least one virtual method, always also write a virtual destructor in the base class.
You can do all this with templates and specialization or type tagging but I take from your question -- coming from Java -- you don't want to go there yet. You really like virtual methods, don't you? Sorry, that you have to mark them in C++.
If you're willing to limit yourself to types known at compile-time (rather than working through pointers on instances of classes with vtables) - then C++11 and later does have an instanceof equivalent: It is std::is_base_of.
You might also want to check out std::is_convertible and std::is_same.
I'm sure you all know the behaviour I mean - code such as:
Thread thread = new Thread();
int activeCount = thread.activeCount();
provokes a compiler warning. Why isn't it an error?
EDIT:
To be clear: question has nothing to do with Threads. I realise Thread examples are often given when discussing this because of the potential to really mess things up with them. But really the problem is that such usage is always nonsense and you can't (competently) write such a call and mean it. Any example of this type of method call would be barmy. Here's another:
String hello = "hello";
String number123AsString = hello.valueOf(123);
Which makes it look as if each String instance comes with a "String valueOf(int i)" method.
Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)
Just to respond to DJClayworth's point, here's what's allowed in C#:
public class Foo
{
public static void Bar()
{
}
}
public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();
// Static methods in other classes are available via
// the class name
Foo.Bar();
Abc abc = new Abc();
// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}
public static void Def()
{
}
}
Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?
Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?
EDIT: This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:
class Base
{
static void foo()
{
System.out.println("Base.foo()");
}
}
class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}
public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}
As you can see, the execution-time value of b is completely ignored.
Why should it be an error? The instance has access to all the static methods. The static methods can't change the state of the instance (trying to is a compile error).
The problem with the well-known example that you give is very specific to threads, not static method calls. It looks as though you're getting the activeCount() for the thread referred to by thread, but you're really getting the count for the calling thread. This is a logical error that you as a programmer are making. Issuing a warning is the appropriate thing for the compiler to do in this case. It's up to you to heed the warning and fix your code.
EDIT: I realize that the syntax of the language is what's allowing you to write misleading code, but remember that the compiler and its warnings are part of the language too. The language allows you to do something that the compiler considers dubious, but it gives you the warning to make sure you're aware that it could cause problems.
They cannot make it an error anymore, because of all the code that is already out there.
I am with you on that it should be an error.
Maybe there should be an option/profile for the compiler to upgrade some warnings to errors.
Update: When they introduced the assert keyword in 1.4, which has similar potential compatibility issues with old code, they made it available only if you explicitly set the source mode to "1.4". I suppose one could make a it an error in a new source mode "java 7". But I doubt they would do it, considering that all the hassle it would cause. As others have pointed out, it is not strictly necessary to prevent you from writing confusing code. And language changes to Java should be limited to the strictly necessary at this point.
Short answer - the language allows it, so its not an error.
The really important thing, from the compiler's perspective, is that it be able to resolve symbols. In the case of a static method, it needs to know what class to look in for it -- since it's not associated with any particular object. Java's designers obviously decided that since they could determine the class of an object, they could also resolve the class of any static method for that object from any instance of the object. They choose to allow this -- swayed, perhaps, by #TofuBeer's observation -- to give the programmer some convenience. Other language designers have made different choices. I probably would have fallen into the latter camp, but it's not that big of a deal to me. I probably would allow the usage that #TofuBeer mentions, but having allowed it my position on not allowing access from an instance variable is less tenable.
Likely for the same logical that makes this not an error:
public class X
{
public static void foo()
{
}
public void bar()
{
foo(); // no need to do X.foo();
}
}
It isn't an error because it's part of the spec, but you're obviously asking about the rationale, which we can all guess at.
My guess is that the source of this is actually to allow a method in a class to invoke a static method in the same class without the hassle. Since calling x() is legal (even without the self class name), calling this.x() should be legal as well, and therefore calling via any object was made legal as well.
This also helps encourage users to turn private functions into static if they don't change the state.
Besides, compilers generally try to avoid declaring errors when there is no way that this could lead to a direct error. Since a static method does not change the state or care about the invoking object, it does not cause an actual error (just confusion) to allow this. A warning suffices.
The purpose of the instance variable reference is only to supply the type which encloses the static. If you look at the byte code invoking a static via instance.staticMethod or EnclosingClass.staticMethod produces the same invoke static method bytecode. No reference to the instance appears.
The answer as too why it's in there, well it just is. As long as you use the class. and not via an instance you will help avoid confusion in the future.
Probably you can change it in your IDE (in Eclipse Preferences -> Java -> Compiler -> Errors/Warnings)
There's not option for it. In java (like many other lang.) you can have access to all static members of a class through its class name or instance object of that class. That would be up to you and your case and software solution which one you should use that gives you more readability.
It's pretty old topic but still up-to-date and surprisingly bringing higher impact nowadays. As Jon mentioned, it might be just a mistake Java's designers made at the very beginning. But I wouldn't imagine before it can have impact on security.
Many coders know Apache Velocity, flexible and powerful template engine. It's so powerful that it allows to feed template with a set of named objects - stricly considered as objects from programming language (Java originally). Those objects can be accessed from within template like in programming language so for example Java's String instance can be used with all its public fields, properties and methods
$input.isEmpty()
where input is a String, runs directly through JVM and returns true or false to Velocity parser's output). So far so good.
But in Java all objects inherit from Object so our end-users can also put this to the template
$input.getClass()
to get an instance of String Class.
And with this reference they can also call a static method forName(String) on this
$input.getClass().forName("java.io.FileDescriptor")
use any class name and use it to whatever web server's account can do (deface, steal DB content, inspect config files, ...)
This exploit is somehow (in specific context) described here: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
It wouldn't be possible if calling static methods from reference to the instance of class was prohibited.
I'm not saying that a particular programming framework is better than the other one or so but I just want to put a comparison. There's a port of Apache Velocity for .NET. In C# it's not possible to call static methods just from instance's reference what makes exploit like this useless:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
I just consider this:
instanceVar.staticMethod();
to be shorthand for this:
instanceVar.getClass().staticMethod();
If you always had to do this:
SomeClass.staticMethod();
then you wouldn't be able to leverage inheritance for static methods.
That is, by calling the static method via the instance you don't need to know what concrete class the instance is at compile time, only that it implements staticMethod() somewhere along the inheritance chain.
EDIT: This answer is wrong. See comments for details.
I know this question has been asked a lot, but the usual answers are far from satisfying in my view.
given the following class hierarchy:
class SuperClass{}
class SubClass extends SuperClass{}
why does people use this pattern to instantiate SubClass:
SuperClass instance = new SubClass();
instead of this one:
SubClass instance = new SubClass();
Now, the usual answer I see is that this is in order to send instance as an argument to a method that requires an instance of SuperClass like here:
void aFunction(SuperClass param){}
//somewhere else in the code...
...
aFunction(instance);
...
But I can send an instance of SubClass to aFunction regardless of the type of variable that held it! meaning the following code will compile and run with no errors (assuming the previously provided definition of aFunction):
SubClass instance = new SubClass();
aFunction(instance);
In fact, AFAIK variable types are meaningless at runtime. They are used only by the compiler!
Another possible reason to define a variable as SuperClass would be if it had several different subclasses and the variable is supposed to switch it's reference to several of them at runtime, but I for example only saw this happen in class (not super, not sub. just class). Definitly not sufficient to require a general pattern...
The main argument for this type of coding is because of the Liskov Substituion Principle, which states that if X is a subtype of type T, then any instance of T should be able to be swapped out with X.
The advantage of this is simple. Let's say we've got a program that has a properties file, that looks like this:
mode="Run"
And your program looks like this:
public void Program
{
public Mode mode;
public static void main(String[] args)
{
mode = Config.getMode();
mode.run();
}
}
So briefly, this program is going to use the config file to define the mode this program is going to boot up in. In the Config class, getMode() might look like this:
public Mode getMode()
{
String type = getProperty("mode"); // Now equals "Run" in our example.
switch(type)
{
case "Run": return new RunMode();
case "Halt": return new HaltMode();
}
}
Why this wouldn't work otherwise
Now, because you have a reference of type Mode, you can completely change the functionality of your program with simply changing the value of the mode property. If you had public RunMode mode, you would not be able to use this type of functionality.
Why this is a good thing
This pattern has caught on so well because it opens programs up for extensibility. It means that this type of desirable functionality is possible with the smallest amount of changes, should the author desire to implement this kind of functionality. And I mean, come on. You change one word in a config file and completely alter the program flow, without editing a single line of code. That is desirable.
In many cases it doesn't really matter but is considered good style.
You limit the information provided to users of the reference to what is nessary, i.e. that it is an instance of type SuperClass. It doesn't (and shouldn't) matter whether the variable references an object of type SuperClass or SubClass.
Update:
This also is true for local variables that are never used as a parameter etc.
As I said, it often doesn't matter but is considered good style because you might later change the variable to hold a parameter or another sub type of the super type. In that case, if you used the sub type first, your further code (in that single scope, e.g. method) might accidentially rely on the API of one specific sub type and changing the variable to hold another type might break your code.
I'll expand on Chris' example:
Consider you have the following:
RunMode mode = new RunMode();
...
You might now rely on the fact that mode is a RunMode.
However, later you might want to change that line to:
RunMode mode = Config.getMode(); //breaks
Oops, that doesn't compile. Ok, let's change that.
Mode mode = Config.getMode();
That line would compile now, but your further code might break, because you accidentially relied to mode being an instance of RunMode. Note that it might compile but could break at runtime or screw your logic.
SuperClass instance = new SubClass1()
after some lines, you may do instance = new SubClass2();
But if you write, SubClass1 instance = new SubClass1();
after some lines, you can't do instance = new SubClass2()
It is called polymorphis and it is superclass reference to a subclass object.
In fact, AFAIK variable types are meaningless at runtime. They are used
only by the compiler!
Not sure where you read this from. At compile time compiler only know the class of the reference type(so super class in case of polymorphism as you have stated). At runtime java knows the actual type of Object(.getClass()). At compile time java compiler only checks if the invoked method definition is in the class of reference type. Which method to invoke(function overloading) is determined at runtime based on the actual type of the object.
Why polymorphism?
Well google to find more but here is an example. You have a common method draw(Shape s). Now shape can be a Rectangle, a Circle any CustomShape. If you dont use Shape reference in draw() method you will have to create different methods for each type of(subclasses) of shape.
This is from a design point of view, you will have one super class and there can be multiple subclasses where in you want to extend the functionality.
An implementer who will have to write a subclass need only to focus on which methods to override
Hi all I was wondering if I could modify and recompile a Java base class?
I would like to add functions to existing classes and be able to call these functions.
For example, I would like to add a function to java.lang.String, recompile it and use it for my project:
public char[] getInternalValue(){
return value;
}
I was wondering how do we go about doing that?
What you're referring to is called "monkey patching". It's possible in Java, but it isn't advisable and the results can be... uhh interesting. You can download the source for the String class, pop it into a JAR and prepend the bootclasspath with:
-Xbootclasspath/p:MonkeyPatchedString.jar
to replace the built-in String class with your own.
There's an interesting paper on this very subject here.
If you do it, you get incompatible with the java.lang.String class, and with all classes, relying on java.lang.String, which is very, very rarely a good idea.
A second problem could be the license. For self-studying it is perfectly fine, but if you publish your code (compiled or in source) you should read the license terms carefully before.
Since the String class is declared final, you can't even inherit from String, and implement your PacerierString, which seems useful at first sight. But there are so many people, who would have implemented their little helpers, that we would get a lot of SpecialString classes from everywhere.
A common practice would be people, writing a class Foo, and adding a method
public Foo toFoo () {
// some conversion for String representation of Foo
}
to their UniversalToolString.
You may, however, write a Wrapper, which contains a String. You might not pass your Wrapper to a method, which expects a String, but you would need to call its 'toString ()' method, if that happens to be a good candidate for that purpose.
Foo foo = new Foo ("foobar", 42);
foo.setMagic (foo.toString ().length);
Don't do that.
If you want to be evil, you can use reflection to access the byte array of a string. But of course there's no guarantee that that field will exist in the future as is... ok, it probably will, but caveat emptor.