I need to code something like that but I don't know the right syntax in the second structure to have fields containing address to structure of first type.
struct ConditionSet
{
int CondsNbr; // Number of cond-s in the set
bool TabConds [MaxConditions];
string TabCondsLabel [MaxConditions];
int CandleNum [MaxConditions];
bool ExitCondition;
int int1, int2, int3, int4, int5; // user integers
double d1, d2, d3,d4, d5; // user doubles
};
struct Transaction
{
string Strategie_name;
string Symbol;
bool BuyReady;
bool SellReady;
bool BuyRunning;
bool SellRunning;
ConditionSet & conditionsAchat; // HERE, THIS IS NOT A CORRECT SYNTAX
ConditionSet & conditionsVente; // HERE, THIS IS NOT A CORRECT SYNTAX
int ticketAchat;
int ticketVente;
};
If a structure contains variables of the string type and/or object of a dynamic array, the compiler assigns an implicit constructor to such a structure. This constructor resets all the structure members of string type and correctly initializes objects of the dynamic array.
Object Pointers
In MQL4, there is a possibility to dynamically create objects of complex type. This is done by the new operator, which returns a descriptor of the created object. Descriptor is 8 bytes large. Syntactically, object descriptors in MQL4 are similar to pointers in C++.
MyObject* hobject= new MyObject();
In contrast to C++, the hobject variable from example above is not a pointer to memory, but rather an object descriptor. Furthermore, in MQL5 all objects in function parameters must be passed by reference.
//+------------------------------------------------------------------+
//| Objects are always passed by reference |
//+------------------------------------------------------------------+
void PrintObject(Foo &object)
{
Print(__FUNCTION__,": ",object.m_id," Object name=",object.m_name);
}
//+------------------------------------------------------------------+
//| Passing an array of objects |
//+------------------------------------------------------------------+
void PrintObjectsArray(Foo &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
{
PrintObject(objects[i]);
}
}
//+------------------------------------------------------------------+
//| Passing an array of pointers to object |
//+------------------------------------------------------------------+
void PrintPointersArray(Foo* &objects[])
{
int size=ArraySize(objects);
for(int i=0;i<size;i++)
{
PrintObject(objects[i]);
}
}
//+------------------------------------------------------------------+
class Foo
{
public:
string m_name;
int m_id;
static int s_counter;
//--- constructors and desctructors
Foo(void){Setup("noname");};
Foo(string name){Setup(name);};
~Foo(void){};
//--- initializes object of type Foo
void Setup(string name)
{
m_name=name;
s_counter++;
m_id=s_counter;
}
};
//+------------------------------------------------------------------+
int Foo::s_counter=0;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare an object as variable with its automatic creation
Foo foo1;
//--- variant of passing an object by reference
PrintObject(foo1);
//--- declare a pointer to an object and create it using the 'new' operator
Foo *foo2=new Foo("foo2");
//--- variant of passing a pointer to an object by reference
PrintObject(foo2); // pointer to an object is converted automatically by compiler
//--- declare an array of objects of type Foo
Foo foo_objects[5];
//--- variant of passing an array of objects
PrintObjectsArray(foo_objects); // separate function for passing an array of objects
//--- declare an array of pointers to objects of type Foo
Foo *foo_pointers[5];
for(int i=0;i<5;i++)
{
foo_pointers[i]=new Foo("foo_pointer");
}
//--- variant of passing an array of pointers
PrintPointersArray(foo_pointers); // separate function for passing an array of pointers
//--- it is obligatory to delete objects created as pointers before termination
delete(foo2);
//--- delete array of pointers
int size=ArraySize(foo_pointers);
for(int i=0;i<5;i++)
delete(foo_pointers[i]);
//---
}
//+------------------------------------------------------------------+
Keyword this
A variable of class type (object) can be passed both by reference and by pointer. As well as reference, the pointer allows having access to an object. After the object pointer is declared, the new operator should be applied to it to create and initialize it.
The reserved word this is intended for obtaining the reference of the object to itself, which is available inside class or structure methods. this always references to the object, in the method of which it is used, and the expression GetPointer(this) gives the pointer of the object, whose member is the function, in which call of GetPointer() is performed. In MQL4 functions can't return objects, but they can return the object pointer.
Thank you for replying.
After moving the Foo class to the top of the source, and adding the strict property, I could compile your source.
I don't understand the line
int Foo::s_counter=0;
What it does ?
I'm thinking how classes could resolve my problem but it's not easy.
Janfi
Related
So I'm new to learning Kotlin, coming from a C# background. I've been messing around with types and a few other things. I'm trying to create a static class of "WalMartGreeters" that can add greeters to a list, and then call a simple static function to display those. My method(s) takes a string argument/string list to add to the mutable string list but when I attempt to add values to it. I get a pre-compilation error saying "expected String.Companion" "got String" I attempt to change it to cast the String as a String.Companion and then it says the cast is illegal.
The predominant error I get is: Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to kotlin.jvm.internal.StringCompanionObject
fun main(args:Array<String>) {
walMartGreeter.addTo("Jean")
walMartGreeter.addTo("Dale")
walMartGreeter.addTo("Phil")
walMartGreeter.addTo("Chris")
walMartGreeter.listTheWholeFam()
}
class walMartGreeter(val strName:String) {
companion object classList {
var prntList = mutableListOf(String)
fun addTo(strNameToAdd:String) {
prntList.add(strNameToAdd)
}
fun addTo(listOfNames:List<String>) {
for (item in listOfNames) {
prntList.add(item)
}
}
fun listTheWholeFam() {
//println("All I do is $strName")
for(item in prntList) {
println("Hello, $item!")
}
//println("type of mutList: ${mutList.ToString()}")
if(prntList is MutableList) {
println("Yeah, it's a mutableList");
}
}
}
}
First, the code above in your question can't be compiled since the prntList is a MutableList<String.Companion> rather than a MutableList<String>. IF you want the prntList to adds Strings, you need to change its type to MutableList<String>, for example:
var prntList = mutableListOf<String>()
Secondly, the String in mutableListOf(String) is just an qualifier rather than a class. which means the String will be reference to a specific reference in its scope. in your case the qualifier will reference to its companion object.
Members of the companion object can be called by using simply the class name as the qualifier.
For example:
// v--- reference to its companion object
val it:String.Companion = String
On the other hand, you also can make the qualifier reference to a top-level variable, for example:
val String = ""
// v--- reference to the top-level variable
var prntList = mutableListOf(String)
// ^---is a `MutableList<String>` rather than `MutableList<String.Companion>` now
The different between the mutableListOf<String>() and the mutableListOf(String) as below:
// v--- it is a type argument of the `String` class
mutableListOf<String>()
// v--- it is a qualifier that reference to `String.Companion`
mutableListOf(String)
I can't seem to get this working, but I'd be surprised if it wasn't possible in Haxe.
I'm trying to pass a couple of Enum values defined in my game to a function, so that it can then concatenate them as String types and pass that to other functions.
Example:
// In a general Entity class:
public override function kill():Void {
messages.dispatchCombined(entityType, ListMessages.KILLED);
super.kill();
}
And in my Messages.hx class:
package common;
import msignal.Signal.Signal1;
/**
* A Message / Event class using Signals bound to String names.
* #author Pierre Chamberlain
*/
class Messages{
var _messages:MessagesDef;
public function new() {
_messages = new MessagesDef();
}
public function add(pType:String, pCallback:FuncDef) {
if (_messages[pType] == null) {
_messages[pType] = new Signal1<Dynamic>();
}
var signals = _messages[pType];
signals.add( pCallback );
}
public function dispatch(pType:String, pArg:Dynamic):Bool {
var signals = _messages[pType];
if (signals == null) return false;
signals.dispatch(pArg);
return true;
}
//Compiler doesn't like passing enums :(
public inline function addCombined(pSource:Enum, pEvent:Enum, pCallback:FuncDef) {
add( combine(pSource, pEvent), pCallback );
}
public inline function dispatchCombined(pSource:Enum, pEvent:Enum, pArg:Dynamic):Bool {
return dispatch( combine(pSource, pEvent), pArg);
}
//How can I just pass the enum "names" as strings?
static inline function combine(a:Enum, b:Enum):String {
return String(a) + ":" + String(b);
}
}
typedef MessagesDef = Map<String, Signal1<Dynamic>>;
typedef FuncDef = Dynamic->Void;
Note how addCombined, dispatchCombined and combine expect an "Enum" type, but in this case I'm not sure if Haxe actually expects the entire Enum "class" to be passed (ie: ListMessages instead of ListMessages.KILLED) or if a value should work. Anyways, compiler doesn't like it - so I'm assuming another special Type has to be used.
Is there another way to go about passing enums and resolving them to strings?
I think you need EnumValue as parameter type (if it is only for enum values), and use Std.String to convert to String values.
static inline function combine(a:EnumValue, b:EnumValue):String {
return Std.string(a) + ":" + Std.string(b);
}
Of course that can be written smaller using String interpolation:
static inline function combine(a:EnumValue, b:EnumValue):String {
return '$a:$b';
}
Of course that can be 'more dynamic' using type parameters:
static inline function combine<A, B>(a:A, b:B):String {
return '$a:$b';
}
There is totally no need to use Dynamic as suggested. If you use Dynamic, you basically turn off the type system.
live example:
http://try.haxe.org/#a8844
Use Dynamic instead of Enum or pass them as Strings right away since you can always convert to enum from String if you need it later.
Anyway pass the enum as enum:Dynamic and then call Std.string(enum);
EDIT: Using EnumValue is definitely better approach than Dynamic, I use Dynamic in these functions because I send more than just Enums there and I am not worried about type safety in that case.
In this piece of code I don't know why the compiler doesn't let me assign the value 0 to variable x. I highlighted the line that cause the problem.
class List{
private:
int p;
public:
static int x;
void total();
};
void List::total(List *a){
x + = a -> p;
cout<<x;
getch();
x=0; // problem here
}
I also noticed that if I write int List::sum=0 before the function body, program works just fine. I just don't understand why.
I appreciate any help!
You have declared the static in your class but have not defined a variable for it.
class List{
private:
int p;
public:
static int x; // this is just a declaration
void total();
};
You need to define it, normally in the associated cpp file:
List::x = 0; // define variable and initialise
Quoting from here:
9.4.2 Static data members
The declaration of a static data member in its class definition is
not a definition and may be of an incomplete type other than
cv-qualified void. The definition for a static data member
shall appear in a namespace scope enclosing the member's class
definition. In the defi- nition at namespace scope, the name of the
static data member shall be qualified by its class name using the ::
operator. The initializer expression in the definition of a
static data member is in the scope of its class
(basic.scope.class).
The operator += tries to increase the value of x. You need to initialize x before using it.
The use of ref and out is not limited to the passing of value types. They can also be used
when a reference is passed. When ref or out modifies a reference, it causes the reference,
itself, to be passed by reference. This allows a method to change what object the reference
refers to.
what does mean this part ?
When ref or out modifies a reference, it causes the reference,
itself, to be passed by reference. This allows a method to change what object the reference
refers to.
It means that by using ref you can change which object a variable points to, not only the contents of the object.
Let's say that you have a method with a ref parameter, that replaces an object:
public static void Change(ref StringBuilder str) {
str.Append("-end-");
str = new StringBuilder();
str.Append("-start-");
}
When you call it, it will change the variable that you call it with:
StringBuilder a = new StringBuilder();
StringBuilder b = a; // copy the reference
a.Append("begin");
// variables a and b point to the same object:
Console.WriteLine(a); // "begin"
Console.WriteLine(b); // "begin"
Change(b);
// now the variable b has changed
Console.WriteLine(a); // "begin-end-"
Console.WriteLine(b); // "-start-"
You can do something like this:
MyClass myObject = null;
InitializeIfRequired(ref myObject);
// myObject is initialized
...
private void InitializeIfRequired(ref MyClass referenceToInitialize)
{
if (referenceToInitialize == null)
{
referenceToInitialize = new MyClass();
}
}
I have a ref class that contains a pointer to an unmanaged class. the class has some basic types and also a vector of objects of another class. I would like to know the best way to get and set the vector from managed code. Will a memcpy between unmangedb objects be efficient or setting each member variable of unmanagedb?
for ex (assume the class is complete. I am writing what is relevant to the question)
Assume we already have a managed wrapped for struct UnmanagedB called B.
struct UnmanagedA
{
int a;
vector<UnmanagedB> list;
};
public ref class A : public System::IDisposable
{
public:
// properties
property System::UInt32 a
{
System::UInt32 get();
void set(System::UInt32 value);
}
property array<B^>^ list
{
System::array<B^>^ get(); // what is the best way to set and get the vector
void set(array<B^>^ value);
}
private:
UnmanagedA* obj1;
};
This obviously won't be cleanly possible, since UnmanagedA contains a vector of UnmanagedB values, while A exposes an property of type array<B^>. If this is intended and not a typo, you will need to marshall the content of B^ into instances of UnmanagedB. Otherwise, let UnmanagedA hold a std::vector< B* > and take care of proper lifetime management.