Meine Situation ist also: Ich habe zwei Klassen: A, B. A enthält std::vector<B>
, und B benötigt den Funktionszeiger von A, um seine eigenen Operationen zu initialisieren.Zeiger auf Elementfunktionen eines anderen Objekts
(Ich versuche, die Integer-Gruppe und integer Ring mathematische Strukturen in C++ zu implementieren)
Was der sicherste Weg dies zu tun ist? (Ich habe gelernt, dass das Geben von B ein Zeiger auf A unerwartetes Verhalten in A verursacht. Ich versuchte es here.)
Jetzt, dass ich an meinem Computer bin, werde ich meine Codebasis (Ich machte B-Mitgliedsklasse zu A, so als die Abschnitte zu minimieren ich muss abtippen):
Ah
#ifndef A_H
#define A_H
#include <vector>
class A
{
public:
A(int);
static int defaultMultiply(int, int);
int multiply(int, int);
class B
{
public:
typedef int(*defaultMultiplication)(int, int);
typedef int(A::*multiplication)(int, int);
B();
B(int, int, multiplication);
B operator*(const B&);
protected:
int m, parentGroupSize;
multiplication mult;
defaultMultiplication defMult;
};
private:
int n;
std::vector<A::B> elements;
};
#endif
A.cpp
#include "A.h"
#include <new>
A::A()
{
}
A::A(int n)
: n(n), elements(std::vector<A::B>(n))
{
}
int A::defaultMultiply(int x, int y) { return (x * y); }
// special multiplication: integer groups have integer addition modulo the group size as their multiplication
int A::multiply(int x, int y)
{
int a = x % this->n, b = y % this->n;
if (a < 0) a += this->n;
if (b < 0) b += this->n;
return ((a + b) % n);
}
A::B::B()
: m(0),
parentGroupSize(0),
mult(0),
defMult(&A::defaultMultiply) // right?
{
}
A::B::B(int m, int n, multiplication mult)
: parentGroupSize(n), mult(mult), defMult(0)
{
// this->m must be in [0, g->size() - 1], if n is larger than 1
if (n > 1)
{
this->m = m % n;
if (this->m < 0) this->m = n + this->m;
}
else
{
this->m = m;
}
}
A::B A::B::operator*(const A::B& b)
{
if (this->parentGroupSize == b.parentGroupSize)
{
if (this->mult)
{
return A::B::B((this->*mult)(this->m, b.m), this->parentGroupSize, &A::B::mult); // I tried using this->mult for last argument, but it wouldn't take it
}
}
return A::B(); // or something similar
}
int A::B::val() const { return this->m; }
main.cpp
#include <iostream>
#include "A.h"
using namespace std;
int main()
{
A(26); // didn't implement any methods to get B's from A, since I am merely testing compilation. I'm trying for that ever-elusive MCVE with just this...
}
Oh, ich verstehe auch die folgende Fehlermeldung: error: pointer to member type 'int (A::)(int, int)' incompatible with object type 'A::B'
Definieren Sie "sicherste". Bitte entfernen Sie auch alle irrelevanten Codes, die nichts mit der Frage zu tun haben. Ich bezweifle, dass die Details all dieser mathematischen Operationen in irgendeiner Weise für diese Frage relevant sind. –
Wenn ein B oder A den Gültigkeitsbereich verlässt, treten keine Segmentfehler auf, z. B. weil entweder eine unendliche Zerstörungsschleife oder undichte Zeiger vorhanden sind. –
Sie liefern den Grund, warum es so gemacht wird. –