以下是关于在课堂上使用属性的问题.
我一直在使用公共属性而不是公开地公开成员变量.多数人建议这种方法有助于封装.但是,我不了解封装的优势,使其成为一个属性.
很多人都不知道使用房产的真正原因.他们只是将其作为编码标准的一部分.
有人可以清楚地解释一个属性如何比公共成员变量更好以及它如何改善封装?
我正在尝试创建一个类,用户可以在其中修改成员变量以更改其成员函数的默认参数.
class Class
{
public int Member;
public void Method(int Argument = Member)
{
// This compiles fine, until I try to actually use
// the method elsewhere in code!
// "Error: need 'this' to access member Member"
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的解决方法是使用幻数,这显然不太理想.
public void Method(int Argument = 123)
{
int RealArgument;
if (Argument == 123) RealArgument = Member;
else RealArgument = Argument;
}
Run Code Online (Sandbox Code Playgroud)
有更好的方法,还是我坚持使用这种"黑客"解决方案?
parameters d member-functions member-variables default-arguments
我对C#有点新,但我在编程方面有相当广泛的背景.
我正在尝试做什么:为游戏定义不同的MapTiles.我已经像这样定义了基本的MapTile类:
public class MapTile
{
public Texture2D texture;
public Rectangle mapRectangle;
public MapTile(Rectangle rectangle)
{
this.mapRectangle = rectangle;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我定义一个子类GrassTile,如下所示:
class GrassTile : MapTile
{
new Texture2D texture = Main.GrassTileTexture;
new public Rectangle mapRectangle;
public GrassTile(Rectangle rectangle) : base(rectangle)
{
this.mapRectangle = rectangle;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的Main类中,我正在创建一个像这样的新maptile:
Maptile testTile;
testTile = new GrassTile(new Rectangle(0, 0, 50, 50);
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试渲染此testTile时,其纹理最终为null.如果我在MapTile中定义纹理,我的代码工作正常,所以它与我以前的实现无关.
那么我怎样才能让GrassTile能够修改MapTile的成员变量纹理呢?或者让我的主类识别GrassTile的纹理,而不是MapTile,我也搞乱了接口,但我不能声明接口成员变量.我还没有得到C#继承的其他内容吗?
提前致谢
我见过大多数人在类中使用成员变量:
string _foo;
public string foo { get { return _foo; }; private set { _foo = value}; }
Run Code Online (Sandbox Code Playgroud)
但是这有什么不同呢?
public string foo { get; private set; }
Run Code Online (Sandbox Code Playgroud) 基本上我的问题是我正在使用的库中的函数(在此代码中为函数Foo)需要一个指向对象(Object*mbar)的指针作为参数.但是,mbar是bar的私有成员变量.
通常,我只是使用一个getter并传递值,但如果我传递指针,那将直接访问资源,这将破坏封装.任何代码都可以调用getter并获得自由统治来修改它.
接下来我想到的是我可以使用const指针因为它们不允许修改它们所指向的资源,但据我所知,我需要修改Foo来接受它,这是不可能的,因为它是一个库函数.
我能想到的最后一件事就是使用Bar的朋友来打电话给FoobarFunction,但我总是被告知朋友的功能是最后的选择.
有没有办法在不破坏封装的情况下做到这一点?
//Main.cpp
#include "Foobar.h"
int main()
{
Foobar fb;
Bar b;
fb.FoobarFunction(b);
return 0;
}
//Bar.h
#include "Object.h"
class Bar
{
private:
Object* mbar;
};
//Foobar.h
#include "Foo.h"
#include "Bar.h"
class Foobar
{
public:
void FoobarFunction(Bar bar)
{
Foo(bar.mbar);
}
};
Run Code Online (Sandbox Code Playgroud) 这个问题似乎有点怪异,但我将尝试对用例进行一点争议。
假设您有一个二维(笛卡尔)字段的通用实现,该字段的尺寸为dim1和dim2,坐标为c1和c2。
struct Field2D {
struct size_type {
size_t dim1,dim2;
};
struct coordinates {
size_t c1,c2;
}
Field2D(size_type const & siz) : size_(siz), data(size_.dim1*size_.dim2) {}
double get(coordinates const & coords) {
return data_[coords.c1*size_.dim2 + coords.c2];
}
//Other methods
private:
size_type size_;
vector<double> data_;
};
Run Code Online (Sandbox Code Playgroud)
您想从此类继承,但您想更明确地了解坐标的性质。例如,一个字段PositionVersusTime,其坐标为“ x”和“ t”,尺寸为“ nx”和“ nt”,我想将其用法
int main(){
PositionVersusTime::size_type siz;
siz.nx = 5;
siz.nt = 2;
PositionVersusTime myField(siz);
PositionVersusTime::coordinates coords;
coords.x = 2;
coords.t = 0;
auto out = myField.get(coords);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我要执行此操作的原因是,排序可能会根据字段(例如TimeVersusPosition)而改变,有时会被用户“遗忘”。有没有办法获得类似的行为?还是我应该简单地使用吸气剂(例如,coords.x()= 2)?
我有一个成员变量,enabled_m其值取决于许多变量.由于这些不变量应该由类维护,我希望它是private:
class foo_t
{
public:
void set_this(...); // may affect enabled_m
void set_that(...); // may affect enabled_m
void set_the_other_thing(...); // may affect enabled_m
bool is_enabled() const { return enabled_m; }
private:
bool enabled_m;
};
Run Code Online (Sandbox Code Playgroud)
哪个有效,但我的意图是要求用户foo_t通过课程进行修改 enabled_m.如果用户想要阅读 enabled_m,那应该是允许的操作:
bool my_enabled = foo.enabled_m; // OK
foo.enabled_m = my_enabled; // Error: enabled_m is private
Run Code Online (Sandbox Code Playgroud)
有没有一种方法,使enabled_m public对const操作和private对非const业务,所有这些都无需要求用户去通过访问程序?
我看到人们在初始化列表中的成员变量后放置一个括号.我想知道为什么人们这样做?
例如,我在头文件中有一个STL容器:
class A{
public:
A();
...
private:
vector<string> v;
}
Run Code Online (Sandbox Code Playgroud)
在源文件中:
A::A() : v() {}
Run Code Online (Sandbox Code Playgroud)
我的问题是什么是v()以及为什么人们这样做,因为看起来v看起来不像是初始化为值
我一直在学习链表和节点结构的递归定义一直困扰着我
struct node {
struct node *next;
int data;
};
Run Code Online (Sandbox Code Playgroud)
我想我总是想象自从键入指针后,它会在声明时知道起始地址和它在解除引用时可以访问的内存量.但它不可能,因为它是在任意数量的其他变量之前声明的,这些变量可以构成任何大小的结构.它是仅在取消引用时才弄明白,还是某种内存表在结构定义的末尾和指针可以使用之前被填充?
我有一段通用代码,在实例化时,归结为:
struct A{...};
A f1(){
A ret;
std::pair<A&, int> p(ret, 1);
p = g(); // g returns a pair<A, int>, but I am not interested in g
return ret; // RVO :)
};
Run Code Online (Sandbox Code Playgroud)
据我了解,这将适用于RVO.
问题是,这个其他代码是否会返回ARVO 类型的对象?
A f2(){
std::pair<A, int> p;
p = g();
return p.first; // RVO ?
};
Run Code Online (Sandbox Code Playgroud)
我理解,由于返回对象被遮挡,它不会做RVO或者编译器可能无法选择"优化".但我没有看到为什么它不可能的根本原因,换句话说,我认为一致性,它应该做RVO(我想要).
我问的原因是因为我认为f2代码比较优雅f1.
这最后一个版本应该做RVO吗?如果是这样,它是编译器依赖的吗?
我用gcc 8.1原油测试给出了RVO不工作f2和f3以下:
struct A{
double something;
A() = default;
A(A const& other) : something(other.something){std::cerr << "cc" << …Run Code Online (Sandbox Code Playgroud) member-variables ×10
c++ ×5
c# ×2
oop ×2
pointers ×2
accessor ×1
c ×1
c++11 ×1
const ×1
d ×1
inheritance ×1
parameters ×1
properties ×1
reference ×1
struct ×1
types ×1
variables ×1