1

我学了一点 C#,现在我正在学习 C++。在 C# 中,数据隐藏可以使用 get 和 set 运算符来完成,通过提供“get”而不是“set”,可以将数据成员呈现为“只读”。

这将允许一个类 (Person) 包含另一个类 (Account),这样 Account 类的公共函数对 Person.Account 的用户可用,但用户不能直接更改 Account 类,因为它是读取的 -只要。

这在下面的代码示例中应该更清楚。

我的问题是,由于 C++ 不提供漂亮的 get/set 语法,是否有与下面代码类似的 C++?

using System;

class Person
{
    private string _Name;
    public string Name { get { return _Name; } set { _Name = value; } }

    private Account _Account;
    public Account Account { get { return _Account; } }

    public Person()
    {
        _Name = "";
        _Account = new Account();
    }
}

class Account
{
    private decimal _Balance;
    public decimal Balance { get { return _Balance; } }

    public Account()
    {
        _Balance = 0;
    }
    public void Deposit(decimal deposit)
    {
        _Balance += deposit;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        p.Name = "John Doe";

        // not allowed: p.Account = new Account();
        // Property or indexer 'CSharp.Person.Account' cannot be assigned to -- it is read only

        // allowed: the Account Object's public functions are available
        p.Account.Deposit(1000);

        Console.WriteLine(p.Account.Balance.ToString());
        // console says "1000"
    }
}
4

4 回答 4

3

这些特殊成员在 C# 术语中称为“属性”,在 C++ 中没有直接等价于它们。您可以将成员设为公开,也可以将其设为私有,并定义 getter 和 setter 方法,但您不会拥有 C# 的语法糖,您必须显式调用它们。

实际上,可以在 C++ 中对这种行为进行编码,但它很难看,详见此处:http ://www.cplusplus.com/forum/general/8147/

于 2013-11-09T00:57:06.583 回答
2

这两种语言之间存在根本的脱节。您说您希望该帐户是只读的,但随后您Deposit对其调用了修改函数 ( )。我的 C++ 有线大脑说这是 gobbledygook。但当然,这是因为语言的不同。分配在两种语言中意味着完全不同的东西。在 C++ 中,它只是另一个修改操作。在 C# 中,它重新分配引用以指向不同的对象。(我认为,但我实际上并没有使用 C#,所以我可能是错的)。

现在,我可能会离开这里,但我建议您对于这种特殊情况实际上并不需要此功能。在我看来,它唯一的好处是保持Person.Account唯一引用的对象。所以两个Person对象不共享同一个Account对象。但这在 C++ 中不是必需的。变量是对象。它们不是共享的,除非您使用工具明确地使它们共享(使用引用、指针或智能指针)。所以,你在这里真正想要的,只是一个公共成员。

如果您真的只想禁止分配,那么您可以这样做。只需删除Account. 或者,在 C++11 之前,将其声明为私有且不提供任何实现。

如果我不在这里,您能否更清楚地了解您要通过此完成什么?因为,再一次,说你想要一个只读对象,但你想修改它(你正在通过调用 来做)是没有任何意义的(在 C++ 中Deposit)。我忽略了制作 balance member 的可能性mutable,但这似乎不适合这种情况。

于 2013-11-09T01:08:55.773 回答
1

C++ 似乎没有直接的等价物——它没有考虑到类似属性的东西,而 C# 是因为 java 已经在实现它。然而,像你一样,我想知道这是否有可能,偶然发现了这个小宝石。基本上,它似乎是一种返回您想要的变量的方法 - 并将其设置为 const 以便您一旦拥有它就无法更改它,使其仅在您使用该方法时有效地读取访问它。因此,如果需要,可以使用类似的东西。实际上,如果您考虑一下,“属性”或“getter 和 setter”实际上只是链接中内容的实现 - setter 有一个参数可以将局部变量设置为您想要的值,

于 2013-11-09T01:24:52.277 回答
-1

返回一个shared_ptr<Account>。这样,消费者可以调用 Account 的方法,但不能覆盖 Person._account。

#include <iostream>
#include <memory>

using std::cout;
using std::endl;
using std::shared_ptr;
using std::wstring;


class Account
{
  public:
    long Amount;
};

class Person
{
  private:
    shared_ptr<Account> _account = shared_ptr<Account>(new Account());

  public:
    wstring Name;
    shared_ptr<Account> GetAccount() { return _account; }
    shared_ptr<const Account> GetAccount() const { return _account; } // a const Person has a const Account
};

int main()
{
  Person p;

  shared_ptr<Account> a = p.GetAccount();
  a->Amount = 1;                          // access p.Account
  cout << a->Amount << endl;              // print 1

  Account* b = new Account();
  b->Amount = 2;

  a.reset(b);                             // doesn't affect p.Account

  cout << p.GetAccount()->Amount << endl; // still 1
}

这是有效的,因为返回共享指针会复制它,包括原始指针。对共享容器的更改仅影响副本,但取消引用底层指针会到达原始实例。

于 2013-11-09T05:58:37.077 回答