Erstellen Sie ein Objekt, dessen Status sich bei der Zuweisung ändert

31

Ich finde es zutiefst seltsam, dass dies in Ruby möglich ist (ich werde nicht gleich sagen, wie):

obj = #code redacted

print obj.state # Some value.

LValue = obj

print obj.state # Different value!

Ihre Herausforderung besteht darin, Code ungefähr in dieser Form zu erstellen. Erstellen Sie ein Objekt und weisen Sie es einer Variablen zu. Es sollte ein definiertes Attribut (oder eine deterministische, idempotente Methode) wie stateoben haben, das sich ändert, nachdem das Objekt einem neuen Bezeichner ( LValueoben) zugewiesen wurde , auch wenn Sie den alten Bezeichner ( objoben) weiterhin verwenden, um darauf zu verweisen.

Zur Hervorhebung bearbeiten : stateoder das Äquivalent muss idempotent sein. Die Erstellung eines Accessors, der den Wert ändert oder aus einem anderen Grund unterschiedliche Ergebnisse liefert, wenn er mehrmals hintereinander aufgerufen wird, ist keine gültige Lösung. Oder einfacher gesagt, es muss die Zuweisung sein, die den Zustand ändert.

Jede Sprache mit Zuweisung ist förderfähig, obwohl es wahrscheinlich einige gibt, für die es keine völlig legitime Lösung gibt. Ich werde meine Ruby-Antwort veröffentlichen, wenn sie nach ein paar Tagen niemand anderes erhält, und die Antworten mit den höchsten Stimmen fortlaufend annehmen.

Histokrat
quelle
Muss die LValue = objLeitung benötigt werden, um statesich tatsächlich zu ändern? (Ich könnte einfach eine Eigenschaft in C # erstellen, die jedes Mal erhöht wird, wenn Sie sie erhalten.)
Tim S.
2
Ja, das wollte ich damit sagen, dass die Methode idempotent sein musste. Ich werde bearbeiten, um das klarer zu machen.
Histokrat
OK danke. Ich muss diesen Teil beschönigt haben.
Tim S.
4
Würde es einfach funktionieren, die Nachzählung des Objekts zurückzugeben?
Nick T
Würden destruktive Veränderungen am Objekt selbst vorgenommen? EmacsLisp: (setq a (list "val")) (setq b (nconc a "val2"))zum Beispiel. aendet ("val" . "val2")zu diesem Zeitpunkt zu bewerten .
Jonathan Leech-Pepin

Antworten:

30

C ++

Dies ist mit den richtigen Werkzeugen trivial.

#include <iostream>

using namespace std;

class Obj {
public:
   int state;

   Obj& operator= (Obj& foo) {
      foo.state++;
      this->state = foo.state - 2;
      return *this;
   }
};

int main() {
   Obj a, b, c, d;
   a.state = 3;
   b.state = 4;

   cout << a.state << " " << b.state << "\n";

   c = a;
   d = b;

   cout << a.state << " " << b.state << " " << c.state << " " << d.state << "\n";

   return 0;
}

Ausgabe:

3 4
4 5 2 3
Marinus
quelle
12
In dem Moment, als ich den Titel sah, wusste ich, dass jemand die Bediener überladen würde. Es ist der offensichtliche Weg. Habe eine Gegenstimme.
17

PHP (Debugbuild,> = 5.4)

Wir verwenden refcount des Objekts in einem Getter. (Also, durch die Zuweisung, erhöht sich die Nachzählung und der Wert ändert sich)

class State {
    public function __get($arg) {
        ob_start();
        debug_zval_dump($this); // e.g. "object(State)#1 (0) refcount(6)"
        return ob_get_clean()[29];
    }
}

$obj = new State;
var_dump($obj->state);
$a = $obj;
var_dump($obj->state);
bwoebi
quelle
14

C #

Zwei einfache Möglichkeiten:

class Obj
{
    public int state;
    public static implicit operator int(Obj o)
    {
        return o.state++;
    }
}

static int LValueI;
static Obj LValueM { set { value.state++; } }
static void Main()
{
    var obj = new Obj { state = 1 };
    LValueI = obj;
    Console.WriteLine(obj.state); //2, caused by the implicit cast.

    LValueM = obj;
    Console.WriteLine(obj.state); //3, caused by the property setter.
    Console.ReadLine();
}

Oder wir könnten einfach in den gleichen Speicher schreiben:

[StructLayoutAttribute(LayoutKind.Explicit)]
class Program
{
    [FieldOffset(0)]
    int state = 1;
    [FieldOffset(1)]
    int LValue;

    void Test()
    {
        var obj = this;

        Console.WriteLine(state);  //1
        LValue = state;
        Console.WriteLine(state);  //257
        Console.ReadLine();
    }
    static void Main() { new Program().Test(); }
}
NPSF3000
quelle
12

TeX, viel kürzer als andere Antworten hier

\setbox0=\hbox{Hello world!} % Put stuff in the box 0.
\message{\the\wd0}           % Print the width of the box => non-zero
\setbox2=\box0               % Put the box instead in box 2.
\message{\the\wd0}           % Now box 0 is void, hence has zero width.

Als Schriftsatzsystem hat TeX einen "Box" -Typ, der Schriftsatzmaterial enthält. Da der häufigste Anwendungsfall darin besteht, dieses Material zu verschieben, zu teilen usw., anstatt Kopien davon anzufertigen, werden Boxen normalerweise gelöscht, wenn sie verwendet werden auf eine aktuelle Box im Speicher). Keine Notwendigkeit für Magie.

Bruno Le Floch
quelle
8

C ++ 11 (Also habt ihr unique_ptr / shared_ptr vergessen :-))

#include <iostream>
#include <memory>
using namespace std;
int main() {
    std::unique_ptr<int> u1(new int(0)), u2;
    std::shared_ptr<int> s1 = std::make_shared<int>(0), s2;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    std::cout<<s1.use_count()<<" "<<s2.use_count()<<" "<<std::endl;
    u2 = std::move(u1);
    s2 = s1;
    std::cout<<u1.get()<<" "<<u2.get()<<" "<<std::endl;
    std::cout<<s1.use_count()<<" "<<s2.use_count()<<" "<<std::endl;
   return 0;
}
Abhijit
quelle
7

Fortran 03

Dies ist der Antwort von Hugo D etwas ähnlich, ist aber etwas versteckter (teilweise, weil wer das # $% ^ Objektorientierte Fortran kennt)?

module objects
   implicit none

   type ObjDef
      integer :: state
    contains
      procedure :: initObject
      procedure :: printObject
      procedure :: setNew
   end type
 contains
   subroutine initObject(this)
     class(ObjDef) :: this
     this%state = this%state + 1
   end subroutine initObject

   subroutine printObject(this)
     class(ObjDef) :: this
     print '(a,i0)',"this%state = ",this%state
   end subroutine printObject

   subroutine setNew(this,that)
     class(ObjDef) :: this,that
     that%state = this%state
   end subroutine setNew

end module objects

program objectChange
   use objects
   type(ObjDef) :: a,b

   call initObject(a)
   call printObject(a)
   call b%setNew(a)
   call printObject(a)
end program objectChange

Die Ausgabe ist

this%state = 1
this%state = 0

Wenn Sie herausfinden können, was passiert ist, erhalten Sie Bonuspunkte! Wenn nicht:

Wenn Aufruf der Prozedur setNewin der Form call b%setNew(a), bist implizit das erste Argument, nicht das zweite.

Kyle Kanos
quelle
7

Power Shell

Dadurch wird ein Objekt erstellt, dessen stateEigenschaft die Namen der Variablen sind, die auf das Objekt verweisen.

$a = @{}| Add-Member -MemberType:16 -PassThru state -Value {
        (gv|?{$this -eq $_.Value}|%{$_.Name}) -join ','} 

'Before: ' + $a.state
$b = $a
'After: ' + $a.state

Ausgabe

Before: a,this
After: a,b,this

Hinweis: Dies funktioniert nicht, wenn die Zuweisung in einem untergeordneten Bereich erfolgt.

'Before: ' + $a.state
&{$b = $a}
'After: ' + $a.state

Ausgänge

Before: a,this
After: a,this
Rynant
quelle
Get-Variable ist schlau!
mazzy
5

Perl 5

Hier ist eine Möglichkeit, dies in Perl zu tun:

package Magic {
    sub new { bless {state => 1} }
    use overload '""' => sub { $_[0]{state}++ };
}
use feature 'say';

my $obj = new Magic;
say $obj->{state};
substr($_, 0) = $obj;
say $obj->{state};

Dies gibt aus:

1
2

Erläuterung:

Dies ist eine einfache Anwendung von Überladung . Insbesondere überlade ich den String-Konvertierungsoperator "", der aufgerufen wird, wenn das überladene Objekt zugewiesen wirdsubstr() (was in Perl ein zulässiger Wert ist).

Es gibt auch viele spezielle Variablen in Perl, die alles, was ihnen zugewiesen ist, aufgreifen. Zum Beispiel funktioniert auch Folgendes:

my $obj = new Magic;
say $obj->{state};
$0 = $obj;
say $obj->{state};

Alternative Lösung

Hier ist ein anderer Weg dorthin:

package Magic {
    use Devel::Peek 'SvREFCNT';
    sub new { bless \my $foo }
    sub state { SvREFCNT ${$_[0]} }
}
use feature 'say';

my $obj = new Magic;
say $obj->state;
my $other = $obj;
say $obj->state;

Hier stateist eine Methode (wir könnten sie zu einem Attribut mit weiteren Bindungs- / Überlastungs-Spielereien machen, aber das würde die Dinge komplizieren), die buchstäblich die Anzahl der Verweise auf das Objekt zählt. Anders als in der ersten Lösung müssen Sie also $objeiner normalen Variablen zuweisen , die eine Objektreferenz enthalten kann, um den Status zu ändern.

Ilmari Karonen
quelle
5

JavaScript

Ok, also habe ich eine kürzere Version erstellt, die als SSCCE funktioniert, aber nicht mehr versucht, JavaScript richtig zu analysieren, sodass die Referenzzählung möglicherweise nicht funktioniert, wenn sie in ein komplexeres Skript eingefügt wird.

(function run () {
    var lineOne = getLine (1), a, b, x, y, z;
    var x = {
        get state () {
            var x=/([a-z]+)\s*=\s*([a-z]+)/,c;
            return 1 + Object.keys (c = run.toString ().split ('\n').slice (0,getLine (2)).filter (function (a) {return (x.test (a))}).reduce (function (a,b,c,d) {var r=b.match (x),t=r[2];while (a[t]){t=a[t]};a[r[1]]=t;return a}, {v:0})).reduce (function (a,b) {return (c[b]=="x"?1:0) + a},0)
        }
    };
    console.log (x.state);  //1
    console.log (x.state);  //1
    y = x;
    console.log (x.state);  //2
    z = y;
    console.log (x.state);  //3    
    a = z;
    b = a;
    console.log (x.state);  //5
    a = null;
    console.log (x.state);  //4
    b = null;
    console.log (x.state);  //3
})() //1 1 2 3 5 4 3 

function getLine(n) {
   try {
      to
   } catch (dat) {
      var stack = dat.stack.split('\n');
       for (var i = 0; i < stack.length; i++) {
           if (~stack[i].indexOf ('getLine')) break;          
       }
      return dat.stack.split ('\n')[i + ~~n].match (/:(\d+)/)[1] - ~~window.hasOwnProperty ('__commandLineAPI')
   }
}
C5H8NNaO4
quelle
2
Möchtest du erklären, was du tust?
Ryan
5
... was in aller Welt ist das? O_o
Türklinke
@Doorknob Ein Getter, der das Ergebnis des Aufrufs einer Funktion zurückgibt, die zählt, wie oft in einem Zuweisungsausdruck innerhalb eines bestimmten Quelltextes auf einen Wert verwiesen wird, und dabei die Quelle und die Zeile der umschließenden Funktionen übergibt Getter wurde von als Argumente aufgerufen. Alles andere ist ein unordentlicher provisorischer Tokenizer. --- Ich weiß nicht, wie ich es sonst nennen soll . Mit anderen Worten. Mit anderen Worten: Der Getter zählt die Anzahl der Zuweisungen von Referenzen zu x bis zu der Zeile, von der er aufgerufen wurde, der Rest ist ein nicht fertiger Tokenizer.
C5H8NNaO4
1
Der längste… und der breiteste!
Nicolas Barbulesco
1
@NicolasBarbulesco Ich habe es kürzer gemacht
C5H8NNaO4
4

Python

Es schummelt ein bisschen, aber wie wäre es mit:

import gc
class A(object):
    @property
    def state(self):
        return len(gc.get_referrers(self))

a = A()
print a.state
b = {"x": a}
print a.state
a.y = a
print a.state
del a
print b["x"].state
James_pic
quelle
4

C ++ 11

Dies kann jedoch für andere Sprachen erweitert werden, die implizite / explizite Destruktoren unterstützen

#include <iostream>
using namespace std;

class Foo {
    int *ptr;
public:
    Foo() {
        ptr = new int(0);
    }   
    int state() {
        return *ptr;
    }
    ~Foo() {
        (*ptr)++;
    }
};
int main() {
    Foo a, b;
    cout << a.state() << " " << b.state() << "\n";
    {
        Foo c, d;
        c = a;
        d = b;
    }
   cout << a.state() << " " << b.state()  << "\n";

   return 0;
}

Der Standardzuweisungsoperator erstellt eine flache Kopie. Das empfangende Objekt besitzt also immer noch den Zeiger und jede Änderung wirkt sich implizit auf das ursprüngliche Objekt aus.

Abhijit
quelle
1
Ja, newohne eine einzige deleteim Programm. Obwohl, für diese Aufgabe ist es gut genug, denke ich :)
Ruslan
Was sind die Ausgänge?
Nicolas Barbulesco
1
Soweit ich weiß (C ++ ist weit weg ...), ändert die Zuweisung hier nicht den Status . Bewegen Sie andernfalls die coutLinie vor dem }und prüfen Sie, ob dies funktioniert. :-)
Nicolas Barbulesco
4

Scala

Mit impliziten Konvertierungen können Sie dies erreichen, während Sie einer normalen lokalen Variablen zuweisen:

import scala.language.implicitConversions

class Obj {
  var counter = 0
}

implicit def o2s(x: Obj): String = {
  x.counter += 1
  x.toString
}

val obj = new Obj
println(obj.counter)
val s: String = obj
println(obj.counter)

Dies können Sie auch mit abgeleiteten Typen erreichen:

var s = ""
s = obj

Sie können auch eine benutzerdefinierte Setter-Methode verwenden, allerdings muss der L-Wert ein Feld sein:

object L {
  var _value = new Obj
  def value = _value
  def value_=(x: Obj): Unit = {
    _value = x
    x.counter += 1
  }
}

val obj = new Obj
println(obj.counter)
L.value = obj
println(obj.counter)
Dan Getz
quelle
3

D

struct Obj {
    int state;

    void opAssign (ref Obj other) {
        ++other.state;
    }
}

void main () {
    import std.stdio;

    Obj obj, lvalue;
    writeln(obj);
    lvalue = obj;
    writeln(obj);
}

Ausgabe:

Obj(0)
Obj(1)
Hugo Dubé
quelle
3

Rubin

Wie versprochen, hier ist die Antwort, die die Frage inspiriert hat.

obj = Class.new { def self.state; to_s[/</] ? "Has not been assigned\n" : "Assigned to #{to_s}"; end }

print obj.state

LValue = obj

print obj.state

Class.newerstellt eine anonyme Klasse. Wenn Sie to_seine anonyme Klasse aufrufen, wird die Standardzeichenfolgendarstellung von Objekten angezeigt, die wie folgt aussieht #<Class:0x007fe3b38ed958>. Sobald jedoch die Klasse einer Konstanten zugewiesen wurde, to_swird diese Konstante. In Ruby ist eine Konstante eine Variable, die mit einem Großbuchstaben beginntobj eine Referenz auf die Klasse, mit der sie anonym bleiben kann.

Mein Code wird to_sin eine stateMethode eingebunden , sodass die Ausgabe erfolgt

Has not been assigned
Assigned to LValue

Im Gegensatz zu den meisten hier beschriebenen Lösungen funktioniert dies nur einmal: Wenn Sie objeine andere Konstante zuweisen , wird die Zeichenfolgendarstellung nicht geändert, und es wird auch kein neuer Wert zugewiesen LValue.

Histokrat
quelle
3

In Java

In Java hielt ich das für unmöglich. Aber…

Hauptklasse :

public class MyAppOfCats {

  public static void main(String[] args) {
    Cat tom = new Cat();
    System.out.println(tom.state()); 
    // Output : NOT-BEST-CAT
    Cat.bestCat = tom;
    System.out.println(tom.state());
    // Output : BEST-CAT
  }

}

Klasse Katze:

public class Cat {

  static Cat bestCat;

  public Cat() {
    super();
  }

  public String state() {
      return ((this == Cat.bestCat) ? "BEST-CAT" : "NOT-BEST-CAT");
  }

}

Ich wurde von @tbodt inspiriert.

Nicolas Barbulesco
quelle
1
Ich weiß, dass es kein Code-Golf ist, aber Sie erkennen, dass Sie den Konstruktor einfach entfernen können und er immer noch derselbe ist, oder?
David Conrad
2
Dies ist kein "Objekt, dessen Status sich bei der Zuweisung ändert". Das ist, Sie manipulieren einen globalen Wert und drucken dann etwas basierend darauf. Es ist nicht anders als Cat.x = 2und dann drucken Cat.x.
Chris Hayes
@Chris - Der Objektstatus basiert auf einem "globalen Wert". Der Objektstatus ändert sich also bei der Zuweisung. Die Frage besagt ;-), dass der Staat eine deterministische, idempotente Methode sein kann. Mein Methodenzustand () ist eine solche Methode.
Nicolas Barbulesco
Nein, der Objektstatus ändert sich bei dieser bestimmten Zuordnung . Wenn ich das getan Cat otherCat = tomhätte, hätte sich der Zustand überhaupt nicht geändert. Es fällt mir schwer zu glauben, dass dies dem Buchstaben oder Geist der Regeln entspricht.
Chris Hayes
@ Chris - Natürlich ändert sich das Objekt bei dieser Aufgabe! Die Frage fragt nach einem Objekt, dessen Status durch die Zuweisung geändert werden soll. Nicht für ein Objekt, dessen Status durch eine Zuweisung geändert werden kann.
Nicolas Barbulesco
3

C ++

Dieses Verhalten ist tatsächlich im Standard festgelegt (und wurde deshalb nicht mehr empfohlen).

#include<iostream>
#include<memory>
int main()
{
    std::auto_ptr<int> a(new int(0));
    std::cout<<a.get()<<'\n';
    std::auto_ptr<int> b = a;
    std::cout<<a.get()<<'\n';
}

Ausgabe

some address
0

Der Prozess, der dies verursacht, ist derselbe wie bei Abhijit, jedoch ohne std::moveund derselbe wie bei Marinus, jedoch unter Verwendung einer Standardklasse, anstatt sie selbst zu definieren.

Bearbeiten: Ich füge eine Erklärung hinzu. In der Ausgabe ist "irgendeine Adresse" tatsächlich ein Hexadezimalwert für die Adresse der zugewiesenen Ganzzahl. std::auto_ptrGibt den Speicherzeiger frei, wenn er einem anderen zugewiesen wurde, auto_ptrund setzt den internen Zeiger auf 0. Durch Aufrufen wird der get()Zugriff auf den Speicherzeiger abgerufen.

JKor
quelle
Ich vermute, dass die "Ausgabe" hier nicht die tatsächliche Ausgabe ist.
Nicolas Barbulesco
Können Sie erklären, was dies tun soll? Vor allem die Methode get()? Warum würde es am Ende 0 zurückgeben?
Nicolas Barbulesco
@Nicholas yep. Diese Ausgabe ist nicht die wahre Ausgabe, sondern eine allgemeinere Ausgabe (ich hatte auch keinen Zugriff auf einen Compiler, so dass ich zu diesem Zeitpunkt kein Beispiel für eine gültige Adresse hatte).
JKor
1
Hm, dies kann auf gcc 4.8 nicht kompiliert werden.
Michael Hampton
1
Ich habe die Kompilierungsfehler behoben. Es gibt immer noch Warnungen, wenn Sie für C ++ 11 kompilieren, weil auto_ptres veraltet ist.
JKor
3

Python

import sys
class K:state = property(sys.getrefcount)
Pfeffer
quelle
2

Python 2.x

Ich konnte keinen richtigen Weg finden, um dies zu tun, ohne eine zusätzliche Klasse zu definieren.

class State(object):
    def __init__(self):
        self.state = 0
    def __set__(self, obj, other):
        # Keep different references
        other.state += 1
        self.state += 2

class Program(object):
    obj, value = State(), State() # Create two State-objects
    def __init__(self):
        print "Before assignment:", self.obj.state, self.value.state # 0 0
        self.value = self.obj # Set value to obj (supposedly)
        print "After  assignment:", self.obj.state, self.value.state # 1 2
        self.value = self.obj
        print "2nd    assignment:", self.obj.state, self.value.state # 2 4

Program()
seequ
quelle
2

Java

Alle anderen Lösungen verwenden die Form der Operatorüberladung ihrer Sprache. Java hat keine Operatorüberladung, also dachte ich, ich stecke fest. Aber mir ist etwas eingefallen.

Hier ist die Hauptklasse:

public class Program {
    public static void main(String[] args) {
        Thing thing = new Thing(0);
        System.out.println(thing.getState());
        Thing.otherThing = thing;
        Thread.sleep(1);
        System.out.println(thing.getState());
    }
}

Es gibt ein paar verdächtige Zeilen, aber sie würden nichts tun, wenn die ThingKlasse völlig normal wäre. Es ist nicht:

public class Thing {
    private int state;

    public Thing(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }

    // Please do your best to ignore the rest of this class.
    public static volatile Thing otherThing;
    static {
        Thread t = new Thread() {
            public void run() {
                Thing t = otherThing;
                while (true)
                    if (t != otherThing) {
                        t = otherThing;
                        t.state++;
                    }
            }
        };
        t.setDaemon(true);
        t.start();
    }
}

Es ist nicht garantiert, dass es aufgrund der Threads funktioniert, aber ich habe es auf JDK 1.8u5 getestet und es funktioniert dort.

tbodt
quelle
@KyleKanos Hat alle Unicode-Zeichen
beseitigt
1

Common Lisp

Ich definiere Zustand als die Anzahl der an einen Vektor gebundenen speziellen Variablen. Die Zuweisung zu einer speziellen Variablen ändert also den Status.

(defgeneric state (object)
  (:documentation "Get the state of this object."))

(defmethod state ((object vector))
  ;; The state of a vector is the number of symbols bound to it.
  (let ((count 0))
    ;; Iterate each SYM, return COUNT.
    (do-all-symbols (sym count)
      ;; When SYM is bound to this vector, increment COUNT.
      (when (and (boundp sym) (eq (symbol-value sym) object))
    (incf count)))))

(defparameter *a* #(this is a vector))
(defparameter *b* nil)
(defparameter *c* nil)

(print (state *a*))
(setf *b* *a*)
(print (state *a*))
(print (state *a*))
(setf *c* *a*)
(print (state *a*))

Ausgabe:

1 
2 
2 
3 

Es funktioniert nur mit Zuweisungen zu speziellen Variablen, nicht zu lexikalischen Variablen oder zu Slots innerhalb eines Objekts.

Passen Sie das auf do-all-symbols in allen Paketen gesucht wird, sodass Variablen fehlen, die kein Paket enthalten. Es kann vorkommen, dass Symbole, die in mehreren Paketen vorhanden sind, doppelt gezählt werden (wenn ein Paket das Symbol aus einem anderen Paket importiert hat).

Rubin

Ruby ist fast dasselbe, aber ich definiere state als die Anzahl der Konstanten, die sich auf ein Array beziehen.

class Array
  # Get the state of this object.
  def state
    # The state of an array is the number of constants in modules
    # where the constants refer to this array.
    ObjectSpace.each_object(Module).inject(0) {|count, mod|
      count + mod.constants(false).count {|sym|
        begin
          mod.const_get(sym, false).equal?(self)
        rescue NameError
          false
        end
      }
    }
  end
end

A = %i[this is an array]
puts A.state
B = A
puts A.state
puts A.state
C = A
puts A.state

Ausgabe:

state-assign.rb:9:in `const_get': Use RbConfig instead of obsolete and deprecated Config.
1
2
2
3

Dies ist eine Verallgemeinerung der Antwort des Histokraten auf Ruby-Objekte, die keine Klassen oder Module sind. Die Warnung wird angezeigt, weil die Konstante Config den Code, der die Warnung erstellt hat, automatisch lädt.

Kernigh
quelle
0

C ++

Das Ergebnis kann auf verschiedenen Plattformen unterschiedlich sein. Auf ideone getestet .

#include <iostream>
#include <cassert>
// File format: [ciiiiciiii...] a char (1 byte) followed by its state (4 bytes)
// Each group takes 5 bytes
char Buffer[30]; // 5*6, six groups

struct Group {
    char c;
    int state;
};

int main(void) {
    assert(sizeof(char) == 1);
    assert(sizeof(int) == 4);

    Group& first_group = *(Group*)(&Buffer[0]); // Group 1 is at 0
    Group& second_group = *(Group*)(&Buffer[5]); // Group 2 is at 5

    first_group.c = '2';
    first_group.state = 1234;

    std::cout << first_group.state << std::endl;

    second_group = first_group;

    std::cout << first_group.state << std::endl;

    return 0;
}

Ausgabe:

1234
13010
jingyu9575
quelle
0

C #

class A
{
    public int N { get; set; }
    public override string ToString() { return N.ToString(); }
}
class B
{
    public int N { get; set; }
    public override string ToString() { return N.ToString(); }
    public static implicit operator A(B b) { b.N = -b.N; return new A { N = b.N }; }
}
public static void Test()
{
    A a = new A { N = 1 };
    B b = new B { N = 2 };
    Console.WriteLine("a is {0}, b is {1}", a, b);
    Console.WriteLine("a is {0}, b is {1}", a, b);
    a = b;
    Console.WriteLine("a is {0}, b is {1}", a, b);
    Console.WriteLine("a is {0}, b is {1}", a, b);
}

Ausgabe:

a is 1, b is 2
a is 1, b is 2
a is -2, b is -2
a is -2, b is -2
ClickRick
quelle
Was macht das? Überfordert dies den Bediener?= ?
Nicolas Barbulesco
@Nicolas Nicht genau. Es ist beim Casting von einem Bzu einem A, weil das implicit operator A(B b)Nebenwirkungen hat.
ClickRick