Цель структуры, структуры определения типа, в C++

Я посмотрел ответ от «emmby» (ответил 16 июня '11 в 21:29), пункт № 4: «Создайте собственный SSLSocketFactory, который использует встроенный сертификат KeyStore, но использует альтернативный KeyStore для все, что не удается проверить по умолчанию. "

Это упрощенная реализация. Загрузите системное хранилище ключей & amp; объединить с хранилищем ключей приложения.

public HttpClient getNewHttpClient() {
    try {
        InputStream in = null;
        // Load default system keystore
        KeyStore trusted = KeyStore.getInstance(KeyStore.getDefaultType()); 
        try {
            in = new BufferedInputStream(new FileInputStream(System.getProperty("javax.net.ssl.trustStore"))); // Normally: "/system/etc/security/cacerts.bks"
            trusted.load(in, null); // no password is "changeit"
        } finally {
            if (in != null) {
                in.close();
                in = null;
            }
        }

        // Load application keystore & merge with system
        try {
            KeyStore appTrusted = KeyStore.getInstance("BKS"); 
            in = context.getResources().openRawResource(R.raw.mykeystore);
            appTrusted.load(in, null); // no password is "changeit"
            for (Enumeration e = appTrusted.aliases(); e.hasMoreElements();) {
                final String alias = e.nextElement();
                final KeyStore.Entry entry = appTrusted.getEntry(alias, null);
                trusted.setEntry(System.currentTimeMillis() + ":" + alias, entry, null);
            }
        } finally {
            if (in != null) {
                in.close();
                in = null;
            }
        }

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

        SSLSocketFactory sf = new SSLSocketFactory(trusted);
        sf.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", sf, 443));

        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

        return new DefaultHttpClient(ccm, params);
    } catch (Exception e) {
        return new DefaultHttpClient();
    }
}

Простой режим для преобразования из JKS в BKS:

keytool -importkeystore -destkeystore cacerts.bks -deststoretype BKS -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk16-141.jar -deststorepass changeit -srcstorepass changeit -srckeystore $JAVA_HOME/jre/lib/security/cacerts -srcstoretype JKS -noprompt

* Примечание. В Android 4.0 (ICS) изменилось хранилище доверия, дополнительная информация: http: // nelenkov.blogspot.com.es/2011/12/ics-trust-store-implementation.html

15
задан Ben Lakey 5 July 2009 в 12:13
поделиться

6 ответов

Версия typedef - это частный случай

typedef foo bar;

, который определяет новый «тип» bar как псевдоним для foo. В вашем случае foo оказывается структурой. В C это был единственный способ ввести новые «типы» (в кавычках, потому что они на самом деле не эквивалентны int, float и co). В C ++ это не так полезно, потому что C ++ был разработан, чтобы сделать определение новых типов более простым и полным, чем C (по крайней мере, в начале C ++), а typedef даже не требуется для ссылки на ранее объявленную структуру ( или класс).

12
ответ дан 1 December 2019 в 00:45
поделиться

Вот различия между двумя объявлениями / определениями:


1) Вы не можете использовать имя typedef для идентификации конструктора или деструктора

struct MyStruct { MyStruct(); ~MyStruct(); }; // ok

typedef struct { MyStructTD(); ~MyStructTD(); } MyStructTD; // not ok

// now consider 
typedef struct MyStruct2 { MyStruct2(); } MyStructTD2; // ok

MyStructTD2::MyStruct2() { } // ok
MyStructTD2::MyStructTD2() { } // not ok

2) Вы не можете скрыть имя typedef например, вы можете ввести имя через заголовок класса - или, наоборот, если у вас уже есть функция или объект с определенным именем, вы все равно можете объявить класс с этим именем, используя заголовок класса, но не через подход typedef.

struct MyStruct { }; // ok

typedef struct { } MyStructTD; // ok

void MyStruct() { }  // (1) - ok Hides struct MyStruct
void MyStructTD() { }  // (2) - not-ok - ill-formed

//> Or if you flip it around, consider in a new translation unit:

void MyStruct() { }   // ok
void MyStructTD() { }   // ok

struct MyStruct { }; // ok
typedef struct { } MyStructTD; // Not ok

3) Вы не можете использовать имя typedef в подробном описателе типа

struct MyStruct {  }; // ok

typedef struct { } MyStructTD; // ok

int main()
{
  void MyStruct(); 
  void MyStructTD(); // ok - new declarative region

  struct MyStruct ms; // ok - names the type
  struct MyStructTD ms2; // not ok - cannot use typedef-name here

}

struct AnotherStruct 
{ 
    friend struct MyStruct;  // ok
    friend struct MyStructTD; // not ok
};

4) Вы не можете использовать его для определения вложенных структур

struct S { struct M; };

typedef struct { } S::M;  // not ok

struct S::M { }; // ok

Как видите, между ними есть заметная разница. Некоторые причуды typedefs являются результатом совместимости с C (именно поэтому, я считаю, существуют оба способа) - и в большинстве случаев объявление имени в заголовке класса более естественно для C ++ - оно имеет свои преимущества (особенно когда вам нужно определить конструкторы и деструкторы) и поэтому предпочтительнее. Если вы пишете код, который должен быть совместим с C и C ++, то есть преимущества от использования обоих подходов. Но если вы пишете чистый C ++, я считаю, что указание имени класса в заголовке класса более читабельно.

22
ответ дан 1 December 2019 в 00:45
поделиться

Последний предназначен для совместимости с C - используйте первый в новом коде C ++.

7
ответ дан 1 December 2019 в 00:45
поделиться

Вы должны использовать typedef, поэтому вам не нужно указывать ключевое слово struct при объявлении переменных этой структуры.

Без typedef:

struct MyStruct foo;

С typedef:

MyStruct foo;

В основном вы создание MyStruct как нового типа, поэтому он также реализует некоторый уровень абстракции типов, поскольку программистам не нужно явно знать, какой это тип. Вы можете передать MyStruct в функцию, управлять данными в ней и возвращать их, и программисту не нужно беспокоиться о том, что на самом деле происходит.

Большая часть стандартной библиотеки C использует typedef по этой причине.

2
ответ дан 1 December 2019 в 00:45
поделиться

"struct MyStruct {};" construct неявно определяет эквивалентный typedef, поэтому обычно это предпочтительное современное использование. Есть еще несколько применений typedef, в основном с указателями на структуры. Например,

typedef struct MyStruct* MyStructPtr;
0
ответ дан 1 December 2019 в 00:45
поделиться

Есть много ответов, в которых оба подхода рассматриваются как эквивалентные, но это не так.

Ключевое слово typedef используется для создания псевдонима типа, то есть обеспечивает новый способ ссылки на другой тип. Когда вы используете typedef struct {} XXX; , вы фактически создаете безымянный тип, а затем создаете псевдоним XXX для этого безымянного типа. С другой стороны, когда вы набираете struct XXX {} ​​.

Пожалуйста, прочтите ответ Майкла Берра здесь (это лучший ответ, чем тот, который был принят на этот вопрос .

0
ответ дан 1 December 2019 в 00:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: