Why following code doesnt override base class property in C++ CLI? - visual-c++

I'm a C# programmer and don't know much about C++.
Any idea why I'm getting error ?
ref class masterWeapon{
public :
virtual property int Slot {
int get(){
return -1;
}
}
};
ref class Weapon1 : masterWeapon{
public :
virtual property int Slot{
//following like throw an error : cannot override base class method
int get() override = masterWeapon::Slot::get{
return 1;
}
}
};

Just remove the = masterWeapon::Slot::get portion and it will compile. If you read the error message that accompanies C3764 it makes this a bit more obvious (but not 100%):
...because the base method is explicitly overridden by 'Weapon1::Slot::get'
Giving us the following code:
ref class Weapon1 : masterWeapon{
public :
virtual property int Slot {
int get() override {
return 1;
}
}
};
Which when run against:
masterWeapon^ weapon1 = gcnew masterWeapon();
masterWeapon^ weapon2 = gcnew Weapon1();
Console::WriteLine(L"weapon1->Slot = {0}", weapon1->Slot);
Console::WriteLine(L"weapon2->Slot = {0}", weapon2->Slot);
Results in:
weapon1->Slot = -1
weapon2->Slot = 1

Related

"Int should be Void -> Int" when comparing two integers

So this is a new one for me. When I try to compare 2 integers, the error tells me that Int should be Void -> Int, which is something I have never even seen before.
The code:
public static function whenTouchEnds(event:TouchEvent){
for (item in currentTouches){
if (item.getId == event.touchPointID){
currentTouches.remove(item);
trace("removed touch");
break;
}
}
}
Following the Haxe documentation, I also tried:
public static function whenTouchEnds(event:TouchEvent){
for (item in currentTouches){
if (item.getId == event.touchPointID) break;
}
}
And for the sake of trail and error (hobby programmer here) even tried:
public static function whenTouchEnds(event:TouchEvent){
for (item in currentTouches){
var itemID:Int = item.getId;
var touchID:Int = event.touchPointID;
if (itemID == touchID){
currentTouches.remove(item);
trace("removed touch");
break;
}
}
}
They all gave me the same error message "Int should be Void -> Int". Here is the Touch class I created which returns an Integer with the getId function:
class Touch
{
public var id:Int = 0;
public var xPos:Int = 0;
public var yPos:Int = 0;
public function new(Id:Int, X:Int, Y:Int)
{
id = Id;
xPos = X;
yPos = Y;
}
public function getX() : Int
{
return (xPos);
}
public function getY() : Int
{
return (yPos);
}
public function getId() : Int
{
return (id);
}
}
I'm not looking for a simple solution, but rather an explanation of what I am missing here. The more I learn, the better!
Cheers
The culprit is this line:
if (item.getId == event.touchPointID)
Since there's no parentheses, you're not actually calling the getId() function here - you're comparing it to an integer (which doesn't make sense). Try this instead:
if (item.getId() == event.touchPointID)
Void -> Int is Haxe's notation for a function type, specifically a function that takes no parameters (Void) and returns an integer. You're comparing such a function to an Int, hence the error message "Int should be Void -> Int".
A small code style critique: the get* functions in your Touch class don't really seem to serve any purpose, the variables are public anyway. If you ever want to do something more complex than just returning the variable in a getter function, you might want to look into using properties instead.

Update a mixed type activity in GetStream.IO using the java stream client loses the type attribute

I have taken the MixedType example code that comes with the java stream client (https://github.com/GetStream/stream-java) and added a update step using updateActivities. After the update the activity stored in stream loses the 'type' attribute. Jackson uses this attribute when you get the activities again and it is deserialising them.
So I get:
Exception in thread "main" Disconnected from the target VM, address: '127.0.0.1:60016', transport: 'socket'
com.fasterxml.jackson.databind.JsonMappingException: Could not resolve type id 'null' into a subtype of [simple type, class io.getstream.client.apache.example.mixtype.MixedType$Match]
at [Source: org.apache.http.client.entity.LazyDecompressingInputStream#29ad44e3; line: 1, column: 619] (through reference chain: io.getstream.client.model.beans.StreamResponse["results"]->java.util.ArrayList[1])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.unknownTypeException(DeserializationContext.java:849)
See here where I have updated the example:
https://github.com/puntaa/stream-java/blob/master/stream-repo-apache/src/test/java/io/getstream/client/apache/example/mixtype/MixedType.java
Any idea what is going on here?
The issue here is originated by Jackson which cannot get the actual instance type of an object inside the collection due to the Java type erasure, if you want to know more about it please read this issue: https://github.com/FasterXML/jackson-databind/issues/336 (which also provides some possible workarounds).
The easiest way to solve it, would be to manually force the value of the property type from within the subclass as shown in the example below:
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
#JsonSubTypes({
#JsonSubTypes.Type(value = VolleyballMatch.class, name = "volley"),
#JsonSubTypes.Type(value = FootballMatch.class, name = "football")
})
static abstract class Match extends BaseActivity {
private String type;
public String getType() {
return type;
}
}
static class VolleyballMatch extends Match {
private int nrOfServed;
private int nrOfBlocked;
public VolleyballMatch() {
super.type = "volley";
}
public int getNrOfServed() {
return nrOfServed;
}
public void setNrOfServed(int nrOfServed) {
this.nrOfServed = nrOfServed;
}
public void setNrOfBlocked(int nrOfBlocked) {
this.nrOfBlocked = nrOfBlocked;
}
public int getNrOfBlocked() {
return nrOfBlocked;
}
}
static class FootballMatch extends Match {
private int nrOfPenalty;
private int nrOfScore;
public FootballMatch() {
super.type = "football";
}
public int getNrOfPenalty() {
return nrOfPenalty;
}
public void setNrOfPenalty(int nrOfPenalty) {
this.nrOfPenalty = nrOfPenalty;
}
public int getNrOfScore() {
return nrOfScore;
}
public void setNrOfScore(int nrOfScore) {
this.nrOfScore = nrOfScore;
}
}

Are accessors / mutators auto-defined in Groovy?

In the section on handling Java Beans with Groovy of Groovy In Action, I found this script (slightly modified):
class Book{
String title
}
def groovyBook = new Book()
// explicit way
groovyBook.setTitle('What the heck, really ?')
println groovyBook.getTitle()
// short-hand way
groovyBook.title = 'I am so confused'
println groovyBook.title
There are no such methods in the class Book so how does that work ?
Yes, they are auto defined and calling book.title is actually calling book.getTitle()
See http://groovy.codehaus.org/Groovy+Beans
You can see this in action with the following script:
def debug( clazz ) {
println '----'
clazz.metaClass.methods.findAll { it.name.endsWith( 'Name' ) || it.name.endsWith( 'Age' ) }.each { println it }
}
class A {
String name
int age
}
debug( A )
// Prints
// public int A.getAge()
// public java.lang.String A.getName()
// public void A.setAge(int)
// public void A.setName(java.lang.String)
// Make name final
class B {
final String name
int age
}
debug( B )
// Prints
// public int B.getAge()
// public java.lang.String B.getName()
// public void B.setAge(int)
// Make name private
class C {
private String name
int age
}
debug( C )
// Prints
// public int C.getAge()
// public void C.setAge(int)
// Try protected
class D {
protected String name
int age
}
debug( D )
// Prints
// public int D.getAge()
// public void D.setAge(int)
// And public?
class E {
public String name
int age
}
debug( E )
// Prints
// public int E.getAge()
// public void E.setAge(int)
Several notes:
For all property fields(public ones only), there are autogenerated accesors.
Default visibility is public. So, you should use private/protected keyword to restrict accessor generation.
Inside an accessor there is direct field access. like this.#title
Inside a constructor you have direct access to! This may be unexpected.
For boolean values there are two getters with is and get prefixes.
Each method with such prefixes, even java ones are treated as accessor, and can be referenced in groovy using short syntax.
But sometimes, if you have ambiguous call there may be class cast exception.
Example code for 4-th point.
class A{
private int i = 0;
A(){
i = 4
println("Constructor has direct access. i = $i")
}
void setI(int val) { i = val; println("i is set to $i"); }
int getI(){i}
}
def a = new A() // Constructor has direct access. i = 4
a.i = 5 // i is set to 5
println a.i // 5
​
4-th note is important, if you have some logic in accessor, and want it to be applied every time you call it. So in constructor you should explicit call setI() method!
Example for 7
class A{
private int i = 0;
void setI(String val) { println("String version.")}
void setI(int val) { i = val; println("i is set to $i"); }
}
def a = new A()
a.i = 5 // i is set to 5
a.i = "1s5" // GroovyCastException: Cannot cast object '1s5' with class 'java.lang.String' to class 'int'
​
So, as I see property-like access uses first declared accessor, and don't support overloading. Maybe will be fixed later.
Groovy generates public accessor / mutator methods for fields when and only when there is no access modifier present. For fields declared as public, private or protected no getters and setters will be created.
For fields declared as final only accessors will be created.
All that applies for static fields analogously.

deserialize SortedSet : why items need to implement IComparable?

I have de folowing classes :
[DataContract]
public class MyProject
{
[DataMember(Name = "Branches")]
private SortedSet<ModuleFilter> branches = new SortedSet<ModuleFilter>(new ModuleFilterComparer());
[DataMember(Name="VbuildFilePath")]
private string buildprogram = null;
}
I can serialize it to a file with :
DataContractSerializer x = new DataContractSerializer(p.GetType());
using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(p.GetFilePath()))
{
x.WriteObject(writer, p);
}
But when I try to read it back with the folowing piece of code, it fails unless I add a dummy implementation of IComparable to the ModuleFilter object
DataContractSerializer x = new DataContractSerializer(typeof(MyProject));
using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(filePath))
{
p = (MyProject)x.ReadObject(reader);
}
Why does not the deserializer use the provided IComparer of the SortedSet member ?
Thank you
It is because DataContractSerializer uses default constructor of SortedSet to initialize field.
Solution 1: recreate field after deserialization with needed comparer
[DataContract]
public class MyProject : IDeserializationCallback
{
//...
void IDeserializationCallback.OnDeserialization(Object sender)
{
branches = new SortedSet<ModuleFilter>(branches, new ModuleFilterComparer());
}
}
Solution 2: use your own sorted set implementation instead of SortedSet<ModuleFilter>
public class ModuleFilterSortedSet : SortedSet<ModuleFilter>
{
public ModuleFilterSortedSet()
: base(new ModuleFilterComparer())
{
}
public ModuleFilterSortedSet(IComparer<ModuleFilter> comparer)
: base(comparer)
{
}
}

Can extension methods modify extended class values?

I was just trying to code the following extension method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _4Testing
{
static class ExtensionMethods
{
public static void AssignMe(this int me, int value)
{
me = value;
}
}
}
But it is not working, i mean, can I use an extension method to alter values from extended classes? I don't want to change void return type to int, just changing extended class value. Thanks in advance
Your example uses int, which is a value type. Classes are reference types and behaves a bit differently in this case.
While you could make a method that takes another reference like AssignMe(this MyClass me, MyClass other), the method would work on a copy of the reference, so if you assign other to me it would only affect the local copy of the reference.
Also, keep in mind that extension methods are just static methods in disguise. I.e. they can only access public members of the extended types.
public sealed class Foo {
public int PublicValue;
private int PrivateValue;
}
public static class FooExtensions {
public static void Bar(this Foo f) {
f.PublicValue = 42;
// Doesn't compile as the extension method doesn't have access to Foo's internals
f.PrivateValue = 42;
}
}
// a work around for extension to a wrapping reference type is following ....
using System;
static class Program
{
static void Main(string[] args)
{
var me = new Integer { value = 5 };
int y = 2;
me.AssignMe(y);
Console.WriteLine(me); // prints 2
Console.ReadLine();
}
public static void AssignMe(this Integer me, int value)
{
me.value = value;
}
}
class Integer
{
public int value { get; set; }
public Integer()
{
value = 0;
}
public override string ToString()
{
return value.ToString();
}
}
Ramon what you really need is a ref modifier on the first (i.e. int me ) parameter of the extension method, but C# does not allow ref modifier on parameters having 'this' modifiers.
[Update]
No workaround should be possible for your particular case of an extension method for a value type. Here is the "reductio ad absurdum" that you are asking for if you are allowed to do what you want to do; consider the C# statement:
5.AssignMe(10);
... now what on earth do you think its suppose to do ? Are you trying to assign 10 to 5 ??
Operator overloading cannot help you either.
This is an old post but I ran into a similar problem trying to implement an extender for the String class.
My original code was this:
public static void Revert(this string s)
{
char[] xc = s.ToCharArray();
s = new string(xc.Reverse());
}
By using the new keyword I am creating a new object and since s is not passed by reference it will not be modified.
I changed it to the following which provides a solution to Ramon's problem:
public static string Reverse(this string s)
{
char[] xc = s.ToCharArray();
Array.Reverse(xc);
return new string(xc);
}
In which case the calling code will be:
s = s.Reverse();
To manipulate integers you can do something like:
public static int Increment(this int i)
{
return i++;
}
i = i.Increment();

Resources