如何限制对 class A 的非常量 public 成员 m 的访问是对另一个 class B 的常量,包含 A 作为非常量成员?
How to restrict access to a non-const public member m of a class A to be const to a another class B, containing A as a non-const member?
a我发现这个问题对其他人来说也很有趣。所以我选择这个来最终问我关于 Stack Overflow 的第一个问题。对该情况的简要描述如下:
class A {
public:
Type_m_first m_first;
Type_m_second m_second;
}
class B { // shoud be const on a.m_first
private:
A& a;
public:
B(A& a_) : a(a_) {};
}
编辑: 将 A
的成员设置为 private
并使用 getter 和 setters 不能解决我的问题。但是,我希望有一个像这样简单的解决方案,因为我可能会因为缺乏编程经验而错过一些简单的东西。
现在,我需要 B
的任何尚未实现的方法只有 const
访问 A.m_first
而没有 const
访问A.m_second
,类似地,在访问 B.a
时,我需要使用具有相同访问限制的 B
类型的任何其他代码。当然,这是不可能的(至少从我的拙见来看是不可能的)。
尽管如此,我的问题是:
如何对 class B
实施这样的 const
限制非 const
成员的访问权限变量?
EDIT With private m_first
and m_second
and a getters and setters for m_first
和 m_second
情况是一样的。那么问题是:如何限制B
对m_first
的const
getter的访问,拒绝B
对[=89=的访问] of m_first
,同时允许 B
使用 m_second
?
的 setter
以上就是问题。但是,如果没有以下上下文,这个问题可能是不完整的,因为它说明了问题的重要性。我面临的实际情况如下:
class A {
public:
Type_m_first m_first;
Type_m_second m_second;
public:
// A lot of code.
private:
// A lot of code.
}
class B { // shoud be const on a.m_first
private:
A& a;
public:
B(A& a_) : a(a_) {};
private:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
public:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
}
class C { // shoud be const on a.m_second
private:
A& a;
public:
C(A& a_) : a(a_) {};
private:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
public:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
}
/*
* A lot of other Code that is supposed to work with A, B and C. The following three
* functions serve as an example. As you see, everything is manipulating essentially
* the same data from a.
*/
void f(A& a, /* other args */ ) { /* ... */ };
void g(B& b, /* other args */ ) { /* ... */ }; // shoud be const on b.a.m_first by design
int h(C& c, /* other args */ ) { /* ... */ }; // shoud be const on c.a.m_second by design
int main() {
A a;
B b = B(a);
C c = C(a);
f(a, /* other args */ );
g(b, /* other args */ );
return h(c, /* other args */ );
}
同样,我需要 B
的任何尚未实现的方法只有 const
访问 A.m_first
而没有 const
访问A.m_second
。但是,对于 class C
我需要完全相反:我需要任何尚未实现的 C
方法只有 const
访问 A.m_second
而非 const
访问 A.m_first
。类似地,任何使用 B
和 C
类型的代码都应该有相应的访问限制。
当然,问题又来了:我为什么需要这个?答案是,算法的逻辑结构将由这样的设计强制执行。使所有内容 public 只是到目前为止的一个问题,因为意外地忽略了逻辑结构会导致很难在代码中找到错误,并且由于代码的复杂性,很难跟踪这样的限制,这些限制是并非由设计强制执行。
我想出但尚未实施的最佳解决方案是将代码复制到两个包装器 classes:
class A_first {
public:
const Type_m_first& m_first;
Type_m_second& m_second;
A_first(A&) ; m_first(const A.m_first), m_second(A.m_second) {};
public:
// Same code as before.
protected:
// Same code as before.
private:
// Same code as before.
}
class A_second {
public:
Type_m_first& m_first;
const Type_m_second& m_second;
A_first(A&) ; m_first(A.m_first), m_second(const A.m_second) {};
public:
// Same code as before.
protected:
// Same code as before.
private:
// Same code as before.
}
这不是我们想要的,因为代码会随着时间的推移发生很多变化,并且跟踪三个 classes 中的变化很容易出错。我的问题是,遇到这种情况怎么办?
好吧,我必须承认,我只是略读了你的问题,所以我可能错过了一些细节。但是 getter 那个 returns 一个 const
参考不是你需要的吗?
class A {
private:
Type_m_first m_first;
public:
const Type_m_first & get_m_first() const { return m_first; }
Type_m_second m_second;
}
这里只有A
的成员可以直接修改m_first
。其他人必须使用通过 get_m_first
.
获得的 const
引用
我非常怀疑这是否值得付出努力,但这可能适合您的需要:
而不是传递 B
和 C
对 A
的引用(这将授予他们无限制地访问 A
,如果我理解正确的话,这就是你的全部问题), 只将访问器传递给两个成员。这可能看起来像这样:
class B {
private:
std::function<Type_m_first const&()> getConstFirst;
std::function<Type_m_second&()> getNonConstSecond;
public:
B(std::function<Type_m_first const&()> f1, std::function<Type_m_second&()> f2)
: getConstFirst(std::move(f1)), getNonConstSecond(std::move(f2)) {};
void someMethod() {
getConstFirst() = abc; // this won't compile
getNonConstSecond() = xyz; // this will
}
}
C
的类似实现。
然后,使用通过引用捕获 A
实例的 lambda 将函数传递给 B
和 C
的 c'tors:
A a;
B b = B(
[&a]() -> auto const& { return a.m_first; },
[&a]() -> auto& { return a.m_second; }
);
C c = C(
[&a]() -> auto& { return a.m_first; },
[&a]() -> auto const& { return a.m_second; }
);
a我发现这个问题对其他人来说也很有趣。所以我选择这个来最终问我关于 Stack Overflow 的第一个问题。对该情况的简要描述如下:
class A {
public:
Type_m_first m_first;
Type_m_second m_second;
}
class B { // shoud be const on a.m_first
private:
A& a;
public:
B(A& a_) : a(a_) {};
}
编辑: 将 A
的成员设置为 private
并使用 getter 和 setters 不能解决我的问题。但是,我希望有一个像这样简单的解决方案,因为我可能会因为缺乏编程经验而错过一些简单的东西。
现在,我需要 B
的任何尚未实现的方法只有 const
访问 A.m_first
而没有 const
访问A.m_second
,类似地,在访问 B.a
时,我需要使用具有相同访问限制的 B
类型的任何其他代码。当然,这是不可能的(至少从我的拙见来看是不可能的)。
尽管如此,我的问题是:
如何对 class B
实施这样的 const
限制非 const
成员的访问权限变量?
EDIT With private m_first
and m_second
and a getters and setters for m_first
和 m_second
情况是一样的。那么问题是:如何限制B
对m_first
的const
getter的访问,拒绝B
对[=89=的访问] of m_first
,同时允许 B
使用 m_second
?
以上就是问题。但是,如果没有以下上下文,这个问题可能是不完整的,因为它说明了问题的重要性。我面临的实际情况如下:
class A {
public:
Type_m_first m_first;
Type_m_second m_second;
public:
// A lot of code.
private:
// A lot of code.
}
class B { // shoud be const on a.m_first
private:
A& a;
public:
B(A& a_) : a(a_) {};
private:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
public:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
}
class C { // shoud be const on a.m_second
private:
A& a;
public:
C(A& a_) : a(a_) {};
private:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
public:
// A lot of code, that I am supposed to move from somewhere else to here
// or write myself.
}
/*
* A lot of other Code that is supposed to work with A, B and C. The following three
* functions serve as an example. As you see, everything is manipulating essentially
* the same data from a.
*/
void f(A& a, /* other args */ ) { /* ... */ };
void g(B& b, /* other args */ ) { /* ... */ }; // shoud be const on b.a.m_first by design
int h(C& c, /* other args */ ) { /* ... */ }; // shoud be const on c.a.m_second by design
int main() {
A a;
B b = B(a);
C c = C(a);
f(a, /* other args */ );
g(b, /* other args */ );
return h(c, /* other args */ );
}
同样,我需要 B
的任何尚未实现的方法只有 const
访问 A.m_first
而没有 const
访问A.m_second
。但是,对于 class C
我需要完全相反:我需要任何尚未实现的 C
方法只有 const
访问 A.m_second
而非 const
访问 A.m_first
。类似地,任何使用 B
和 C
类型的代码都应该有相应的访问限制。
当然,问题又来了:我为什么需要这个?答案是,算法的逻辑结构将由这样的设计强制执行。使所有内容 public 只是到目前为止的一个问题,因为意外地忽略了逻辑结构会导致很难在代码中找到错误,并且由于代码的复杂性,很难跟踪这样的限制,这些限制是并非由设计强制执行。
我想出但尚未实施的最佳解决方案是将代码复制到两个包装器 classes:
class A_first {
public:
const Type_m_first& m_first;
Type_m_second& m_second;
A_first(A&) ; m_first(const A.m_first), m_second(A.m_second) {};
public:
// Same code as before.
protected:
// Same code as before.
private:
// Same code as before.
}
class A_second {
public:
Type_m_first& m_first;
const Type_m_second& m_second;
A_first(A&) ; m_first(A.m_first), m_second(const A.m_second) {};
public:
// Same code as before.
protected:
// Same code as before.
private:
// Same code as before.
}
这不是我们想要的,因为代码会随着时间的推移发生很多变化,并且跟踪三个 classes 中的变化很容易出错。我的问题是,遇到这种情况怎么办?
好吧,我必须承认,我只是略读了你的问题,所以我可能错过了一些细节。但是 getter 那个 returns 一个 const
参考不是你需要的吗?
class A {
private:
Type_m_first m_first;
public:
const Type_m_first & get_m_first() const { return m_first; }
Type_m_second m_second;
}
这里只有A
的成员可以直接修改m_first
。其他人必须使用通过 get_m_first
.
const
引用
我非常怀疑这是否值得付出努力,但这可能适合您的需要:
而不是传递 B
和 C
对 A
的引用(这将授予他们无限制地访问 A
,如果我理解正确的话,这就是你的全部问题), 只将访问器传递给两个成员。这可能看起来像这样:
class B {
private:
std::function<Type_m_first const&()> getConstFirst;
std::function<Type_m_second&()> getNonConstSecond;
public:
B(std::function<Type_m_first const&()> f1, std::function<Type_m_second&()> f2)
: getConstFirst(std::move(f1)), getNonConstSecond(std::move(f2)) {};
void someMethod() {
getConstFirst() = abc; // this won't compile
getNonConstSecond() = xyz; // this will
}
}
C
的类似实现。
然后,使用通过引用捕获 A
实例的 lambda 将函数传递给 B
和 C
的 c'tors:
A a;
B b = B(
[&a]() -> auto const& { return a.m_first; },
[&a]() -> auto& { return a.m_second; }
);
C c = C(
[&a]() -> auto& { return a.m_first; },
[&a]() -> auto const& { return a.m_second; }
);